安卓无线点餐系统客户端——自定义之ScrollView餐桌

参考的一篇文章  :http://my.oschina.net/sfshine/blog/151673

先看一下做出来的效果图

可以滑动切换界面 ,这就要用到了自定义的ScrollLayout了,听说每个安卓程序员都要学会自定义ScrollView,好吧,今天我就边学边用。

可以这样理解,要做出滑动的效果,必须定义一个大于屏幕宽度的Layout,然后通过划动,在屏幕显示形成切换效果。


 之前也有用过ViewPage+Fragment也可以达成这样的效果,不过两者区别较大。

自定义ScrollLayout,继承ViewGroup,主要是重写onLayout() 和 onMeasure()方法。

package com.lin.helper;



import android.R.integer;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;

import android.view.ViewGroup;
import android.widget.Scroller;

public class MyScrollLayout extends ViewGroup {

	private VelocityTracker mVelocityTracker;//判断甩手姿势
	private static final int SNAP_VELOCITY = 600; //定义翻页的速度
	private Scroller mScroller;//
	private int mCurScreen;
	private int mDefaultScreen;
	private float mLastMotionX;
	
	private OnViewChangeListener mOnViewChangeListener; //自定义的接口类

	public MyScrollLayout(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		init(context);
	}
	public MyScrollLayout(Context context,AttributeSet attrs){
		super(context, attrs);
		init(context);
	}
	public MyScrollLayout(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		init(context);
	}
	
	private void init(Context context)
	{
		//初始化数据
		mCurScreen = mDefaultScreen;
		mScroller = new Scroller(context);//自定义Scoller,当滑动时View不会滚动
	}
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		// TODO Auto-generated method stub
		if (changed) {
			//view有新的尺寸或位置
			int childLeft = 0 ;
			final int childCount = getChildCount();
			for(int i =0;i<childCount;i++)
			{
				//生成View(滑动的页面)
				final View childView = getChildAt(i);
				if (childView.getVisibility()!= View.GONE) {
					final int childWidth = childView.getMeasuredWidth();
					childView.layout(childLeft, 0, childLeft+childWidth, childView.getMeasuredHeight());
					childLeft +=childWidth;
				}
			}
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int Width = MeasureSpec.getSize(widthMeasureSpec);
		final int WidthMode = MeasureSpec.getMode(widthMeasureSpec);
		final int Count = getChildCount();
		for(int i = 0;i<Count;i++)
		{
			getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
		}
		scrollTo(mCurScreen*Width, 0);//定位
	}
	
	public void snapToDestination()
	{
		//重置
		final int ScreenWidth = getWidth();
		final int destScreen = (getScrollX()+ScreenWidth/2)/ScreenWidth;
		snapToScreen(destScreen);
	}
	public void snapToScreen(int whichScreen)
	{
		//切换到页面
		whichScreen = Math.max(0, Math.min(whichScreen,getChildCount()-1));//限制不越界
		if (getScrollX() != (whichScreen*getWidth())) {
			final int detla = whichScreen * getWidth() - getScrollX();
			mScroller.startScroll(getScrollX(), 0, detla, 0, Math.abs(detla)*2);//设置切换的效果
			mCurScreen = whichScreen;
			invalidate();//重画Layout
			if (mOnViewChangeListener!=null) {
				mOnViewChangeListener.OnViewChange(mCurScreen);
		}
		
		}
	}
	@Override
	public void computeScroll() {
		// TODO Auto-generated method stub
		if (mScroller.computeScrollOffset()) {
			//位置偏移
			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
			postInvalidate();
		}
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		final int action = event.getAction();
		final float x = event.getX();
		final float y = event.getY();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			//Log.i("", "actiondown");
			if (mVelocityTracker==null) {
				mVelocityTracker = VelocityTracker.obtain();
				mVelocityTracker.addMovement(event);
			}
			if (!mScroller.isFinished()) {
				mScroller.abortAnimation();
			}
			mLastMotionX = x;
			break;
		case MotionEvent.ACTION_MOVE:
			int deltaX =(int)( mLastMotionX - x);
			if (IsCanMove(deltaX)) {
				if (mVelocityTracker!=null) {
					mVelocityTracker.addMovement(event);
				}
				mLastMotionX = x;
				scrollBy(deltaX, 0);
			}
			break;
		case MotionEvent.ACTION_UP:
			int VelocityX = 0;
			if (mVelocityTracker!=null) {
				mVelocityTracker.addMovement(event);
				mVelocityTracker.computeCurrentVelocity(1000);
				VelocityX = (int)mVelocityTracker.getXVelocity();
				}
			if (VelocityX > SNAP_VELOCITY && mCurScreen>0) {
				//可以向左滑动
				snapToScreen(mCurScreen-1);
			}else if (VelocityX < - SNAP_VELOCITY && mCurScreen < getChildCount()-1) {
				//向右滑动
				snapToScreen(mCurScreen+1);
			}else {
				snapToDestination();
			}
			if (mVelocityTracker!= null) {
				mVelocityTracker.recycle();
				mVelocityTracker = null;
			}
			break;
		}
		return true;
	}
	
	public boolean IsCanMove(int deltaX)
	{
		if(getScrollX()<=0 && deltaX<0){
			return false;
		}
		if (getScrollX()>= (getChildCount()-1)*getWidth() && deltaX > 0  ) {
			return false;
		}
		return true;
	}
	public void SetOnViewChangeListenner(OnViewChangeListener listener)
	{
		mOnViewChangeListener = listener;
	}
	
}

一个空白的自定义ScrollLayout就出来了。然后是可以在里面放Gridview,也就是子View,需要多少个页面就可以在xml布局里放多少个Gridview

这里还是用到了自定义的GridView,更美观一些。

package com.lin.helper;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;

public class MyGridView extends GridView{
	public MyGridView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

	//自定义GridView 因为ScrollLayout与GridView都有滚动条,当他们嵌套在一起就会出现问题,所以自定义了一个GridView
	//重写了onMeasure()方法使其不出现滚动条
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2, MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
}
之后就是在布局里应用这两个自定义的组件,跟平常一样


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:background="@drawable/choose_default">
    
    <LinearLayout
        android:id="@+id/c_taglayout"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:background="@android:color/background_light"
	    android:orientation="horizontal">
	    
	    <TextView
	        android:id="@+id/choose_back" 
	        android:layout_width="wrap_content"
	        android:layout_height="32dp"
	        android:gravity="left"
	        android:background="@drawable/back"
	        android:textColor="#EC6806"
	        android:layout_marginLeft="10dp"
	        />

	    <TextView
	        android:id="@+id/choose_tag"
	        android:layout_width="fill_parent"
	        android:layout_height="32dp"
	        android:layout_marginTop="10dp"
	        android:layout_marginLeft="-50dp"
	        android:gravity="center_horizontal"
	        android:text="@string/choose_tag"
	        android:textColor="@android:color/black"
	        android:textSize="18sp" />
	   
	</LinearLayout>
    
    <com.lin.helper.MyScrollLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/ScrollLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/c_taglayout"
        >
       
      
        <com.lin.helper.MyGridView 
            android:id="@+id/gridview_01"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:columnWidth="90dp"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp"
            >
            
            
        </com.lin.helper.MyGridView>
     
       <com.lin.helper.MyGridView 
            android:id="@+id/gridview_02"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:columnWidth="90dp"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp"
           ></com.lin.helper.MyGridView>
        
       <com.lin.helper.MyGridView 
            android:id="@+id/gridview_03"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:columnWidth="90dp"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp"
           ></com.lin.helper.MyGridView>
       
    </com.lin.helper.MyScrollLayout>
    
    <!-- 底部小圆点 -->
    <LinearLayout 
        
        android:id="@+id/llayout"
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="24dp"
        >
        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:padding="15dp"
            android:clickable="true"
            android:src="@drawable/notcurrent"
            android:contentDescription="@null"
            />
        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:padding="15dp"
            android:clickable="true"
            android:src="@drawable/notcurrent"
            android:contentDescription="@null"
            />
        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:padding="15dp"
            android:clickable="true"
            android:src="@drawable/notcurrent"
            android:contentDescription="@null"
            />
        
    </LinearLayout>
    
    

</RelativeLayout>
剩下的都比较简单啦。看看代码就好。

这是主Activity

package com.lin.view;

import java.util.ArrayList;
import java.util.HashMap;

import com.example.order_client.R;
import com.lin.helper.MyGridView;
import com.lin.helper.MyScrollLayout;
import com.lin.helper.OnViewChangeListener;

import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class ChooseTableActivity extends Activity implements OnViewChangeListener ,OnClickListener,OnItemClickListener{
 
	private MyScrollLayout scrollLayout;
	private MyGridView myGridView_01;
	private MyGridView myGridView_02;
	private MyGridView myGridView_03;
	private ImageView[] imageViews;
	private int mViewCount;
	private int mCurSel;
	private  TextView c_tagView;
	private  TextView c_backView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_choosetable);
		scrollLayout = (MyScrollLayout)findViewById(R.id.ScrollLayout);
		myGridView_01 = (MyGridView)findViewById(R.id.gridview_01);
		myGridView_02 = (MyGridView)findViewById(R.id.gridview_02);
		myGridView_03 = (MyGridView)findViewById(R.id.gridview_03);
		c_tagView = (TextView)findViewById(R.id.choose_tag);
		c_backView = (TextView)findViewById(R.id.choose_back);
		c_backView.setOnClickListener(this);
		LinearLayout layout = (LinearLayout)findViewById(R.id.llayout);
		myGridView_01.setAdapter(getMeunAdapter());
		myGridView_02.setAdapter(getMeunAdapter());
		myGridView_03.setAdapter(getMeunAdapter());
		myGridView_01.setOnItemClickListener(this);
		myGridView_02.setOnItemClickListener(this);
		myGridView_03.setOnItemClickListener(this);
		mViewCount = scrollLayout.getChildCount();
		imageViews = new ImageView[mViewCount];
		for (int i = 0; i < mViewCount; i++) {
			//
			imageViews[i]=(ImageView)layout.getChildAt(i);
			imageViews[i].setEnabled(true);
			imageViews[i].setOnClickListener(this);
			imageViews[i].setTag(i);
		}
		mCurSel = 0;
		imageViews[mCurSel].setEnabled(false);
		imageViews[mCurSel].setImageDrawable(getResources().getDrawable(R.drawable.current));
		scrollLayout.SetOnViewChangeListenner(this);
		
	}

	private void setCurPoint(int index)
	{
		//底部小圆点
		if (index<0 ||index == mCurSel || index > mViewCount-1) {
			return;
		}
		imageViews[mCurSel].setEnabled(true);
		imageViews[index].setEnabled(false);
		imageViews[mCurSel].setImageDrawable(getResources().getDrawable(R.drawable.notcurrent));
		imageViews[index].setImageDrawable(getResources().getDrawable(R.drawable.current));
		mCurSel = index ;
		c_tagView.setText(index+1+"楼");
		
	}
	
	
	
	@Override
	public void OnViewChange(int view) {
		// TODO Auto-generated method stub
		setCurPoint(view);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if(v.getClass()==ImageView.class)
		{
			//点击小圆点
			int pos =(Integer) v.getTag();
			setCurPoint(pos);
			scrollLayout.snapToScreen(pos);
		}
		if (v.getId()==c_backView.getId()) {
			
			finish();
		}
		
		System.out.println("click"+v.getId());
	}
	
	private SimpleAdapter getMeunAdapter()
	{
		ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String,Object>>();
		for (int i = 0; i < 12; i++) {
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("itemimage", R.drawable.seat_normal);
			map.put("itemtext", "第"+(i+1)+"桌");
			list.add(map);
		}
		
		SimpleAdapter adapter = new SimpleAdapter(ChooseTableActivity.this, list, R.layout.griditem, 
				new String[]{"itemimage","itemtext"},
				new int[]{R.id.item_image,R.id.item_text});
		return adapter;
		
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View v, int loc, long arg3) {
		// TODO Auto-generated method stub
		int whichfloat =49;
		whichfloat = c_tagView.getText().charAt(0)-48;
		System.out.println(whichfloat+"楼"+(loc+1)+"桌");
		
		
	}
	

}

GridView 的Adapter跟ListView 的比较相似,都要创建两个layout文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
	
    <ImageView 
        android:id="@+id/item_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:contentDescription="@null"
        />
    <TextView 
        android:id="@+id/item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@id/item_image"
        android:textColor="@android:color/white"
        android:textStyle="bold"
        />

</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
     >
    <!-- 用来加载Item -->
    <com.lin.helper.MyGridView 
        android:id="@+id/gridview_only"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:columnWidth="90dp"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:horizontalSpacing="10dp"
        android:verticalSpacing="10dp"
        android:stretchMode="columnWidth"
        
        ></com.lin.helper.MyGridView>

</LinearLayout>


差不多这样啦,上面的MyscrollLayout其实还自定义了一个onViewChangeListerner()接口


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值