zoukankan      html  css  js  c++  java
  • SlidingMenu 左侧滑动菜单

    1.MainActivity

    package loveworld.slidingmenu;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.graphics.Color;
    import android.graphics.drawable.ColorDrawable;
    import android.os.Bundle;
    import android.provider.ContactsContract.CommonDataKinds.Organization;
    import android.view.Gravity;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup.LayoutParams;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            // 左側视图
            View leftViewGroup = createLeftListView();
    		
            // 右側视图
            View listView = createRightListView();
            
            final SlidingMenu mSlidingMenu = new SlidingMenu(this);
            mSlidingMenu.addLeftView(leftViewGroup);
            mSlidingMenu.addRightView(listView);
            
            setContentView(mSlidingMenu);
        }
    
    	
    	private View createLeftListView() {
    		LinearLayout linearLayout = new LinearLayout(getBaseContext());
    		linearLayout.setLayoutParams(new LayoutParams(300, LayoutParams.FILL_PARENT));
    		linearLayout.setOrientation(LinearLayout.VERTICAL);
    		
    		TextView textViewOne = createTextView("俺是首页", Color.BLUE);
    		TextView textViewTwo = createTextView("。。

    。。

    。", Color.GRAY); TextView textViewThree = createTextView("俺是导航", Color.BLUE); TextView textViewFour = createTextView("俺有点丑", Color.GRAY); TextView textViewFive = createTextView("俺是设置", Color.BLUE); linearLayout.addView(textViewOne); linearLayout.addView(textViewTwo); linearLayout.addView(textViewThree); linearLayout.addView(textViewFour); linearLayout.addView(textViewFive); return linearLayout; } private TextView createTextView(final String text, final int color) { TextView textView = new TextView(getBaseContext()); textView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); textView.setText( text ); textView.setPadding(0, 50, 0, 50); textView.setGravity(Gravity.CENTER); textView.setBackgroundColor(color); textView.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Toast.makeText(getBaseContext(), "click " + text, Toast.LENGTH_SHORT).show(); } }); return textView; } private View createRightListView() { ListView listView = new ListView(this); ArrayList<String> arrayList = new ArrayList<String>(); for (int i = 0; i < 30; i++) { arrayList.add("World " + i); } CustomBaseAdapter customBaseAdapter = new CustomBaseAdapter(getBaseContext(), arrayList); listView.setAdapter(customBaseAdapter); listView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); listView.setDivider( new ColorDrawable(Color.BLACK) ); listView.setDividerHeight(1); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) { Toast.makeText(getBaseContext(), "World position = " + position, Toast.LENGTH_SHORT).show(); } }); return listView; } }


    2.SlidingMenu

    package loveworld.slidingmenu;
    
    import android.content.Context;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.widget.Scroller;
    
    
    public class SlidingMenu extends ViewGroup {
    
    	private View mRightView;
    	private View mLeftView;
    	private ScrollRunnable mScrollRunnable;
    	private int mTouchSlop;
    	
    	// 记录按下位置,用于推断当前滚动时向左还是向右
    	private int mInterceptMotionX = 0;
    	
    	// 记录一次移动位置,用于计算移动偏移量
    	private int mLastX;
    	
    	public SlidingMenu(Context context) {
    		super(context);
    		initSlidingMenu(context);
    	}
    
    	public SlidingMenu(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		initSlidingMenu(context);
    	}
    
    	public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    		initSlidingMenu(context);
    	}
    
    	public void addLeftView(View leftView) {
    		mLeftView = leftView;
    		// 由于Touch分发机制,即使右側视图盖住当前视图
    		// 仅仅要VISIBLE状态,都会先接收到Touch Event
    		mLeftView.setVisibility(View.INVISIBLE);
    		addView(leftView);
    	}
    	
    	/**
    	 * 提供右側显示视图
    	 * 
    	 * @param rightView
    	 */
    	public void addRightView(View rightView) {
    		mRightView = rightView;
    		
    		addView(rightView);
    	}
    
    	@Override
    	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    		measureChildren(widthMeasureSpec, heightMeasureSpec);
    
    		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    		
    		setMeasuredDimension(widthSize, heightSize);
    	}
    	
    	@Override
    	protected void onLayout(boolean changed, int l, int t, int r, int b) {
    		
    		if (!changed) {
    			return;
    		}
    		
    		int childCount = getChildCount();
    		for (int i = 0; i < childCount; i++) {
    			View childView = getChildAt(i);
    			
    			int measuredWidth = childView.getMeasuredWidth();
    			int measuredHeight = childView.getMeasuredHeight();
    			
    			childView.layout(l, 0, l + measuredWidth, measuredHeight);
    		}
    	}
    	
    	
    	@Override
    	public boolean onInterceptTouchEvent(MotionEvent ev) {
    		
    		final int actioin = ev.getAction();
    		final int x = (int) ev.getX();
    		
    		switch (actioin) {
    		case MotionEvent.ACTION_DOWN:
    			mInterceptMotionX = x;
    			break;
    
    		case MotionEvent.ACTION_MOVE:
    			final int deltaX = x - mInterceptMotionX;
    			final int distance = Math.abs(deltaX);
    			// 点击区域必须在右側视图,由于仅右側视图可移动
    			// 横向移动超过一定距离,能够自己依据需求修改
    			if ( canSliding(ev) && distance > mTouchSlop * 2) {
    
    				// 置为初始值
    				mLastX = x;
    				if (mScrollRunnable != null) {
    					mScrollRunnable.endScroll();
    					mScrollRunnable = null;
    				}
    				
    				// 拦截Touch Event 交由当前ViewGruop onTouchEvent处理
    				return true;
    			}
    			
    			break;
    			
    		case MotionEvent.ACTION_UP:
    		case MotionEvent.ACTION_CANCEL:	
    			mInterceptMotionX = 0;
    			break;
    		}
    		
    		return false;
    	}
    	
    	
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		
    		final int x = (int) event.getX();
    		
    		switch (event.getAction()) {
    		case MotionEvent.ACTION_MOVE:
    			
    			scrollIfNeed(x);
    			return true;
    			
    		case MotionEvent.ACTION_UP:
    			
    			autoScrollIfNeed(x);
    			break;
    		}
    		
    		return false;
    	}
    
    	private void initSlidingMenu(Context context) {
    		final ViewConfiguration configuration = ViewConfiguration.get(context);
            mTouchSlop = configuration.getScaledTouchSlop();
    	}
    	
    	/**
    	 * 当前手指点击位置是否在右側视图区域内
    	 * 
    	 * @param event
    	 * @return true 能够滚动
    	 */
    	private boolean canSliding(MotionEvent event) {
    		
    		final int scrolledXInt = (int) (event.getX() + getScrollX());
    		final int scrolledYInt = (int) (event.getY() + getScrollY());
    		
    		Rect frame = new Rect();
    		mRightView.getHitRect(frame);
    		if (frame.contains(scrolledXInt, scrolledYInt)) {
    			return true;
    		}
    		
    		return false;
    	}
    	
    	
    	private void scrollIfNeed(final int x) {
    		// 计算与上次的偏移量
    		int deltaX = x - mLastX;
    		
    		// 降低移动次数
    		if (x != mLastX) {
    			// 显示
    			if (mLeftView.getVisibility() != View.VISIBLE) {
    				mLeftView.setVisibility(View.VISIBLE);
    			}
    			
    			int l = mRightView.getLeft();
    			int t = mRightView.getTop();
    			int b = mRightView.getBottom();
    			
    			// 右側视图的滑动区域。仅仅能在左側视图范围内滑动
    			int rightViewLeft = Math.max(mLeftView.getLeft(), l + deltaX);
    			rightViewLeft = Math.min(mLeftView.getRight(), rightViewLeft);
    			
    			// 控制随手指滑动
    			mRightView.layout(rightViewLeft, t, rightViewLeft + mRightView.getWidth(), b);
    		}
    		
    		// 滑动到最左側
    		if (mRightView.getLeft() == mLeftView.getLeft()) {
    			mLeftView.setVisibility(View.INVISIBLE);
    		}
    		
    		// 记录当前值供下次计算		
    		mLastX = x;
    	}
    	
    	
    	private void autoScrollIfNeed(final int x) {
    		mScrollRunnable = new ScrollRunnable();
    		
    		// 用于推断滑动方向
    		final int deltaX = x - mInterceptMotionX;
    		// x轴向右是依次递增与手指落下点差值,小于0说明是手指向左滑动
    		boolean moveLeft = deltaX <= 0;
    		
    		// 滑动距离超过左側视图一半,才会沿着手指方向滚动
    		final int distance = Math.abs(deltaX);
    		if (distance < mLeftView.getWidth() / 2) {
    			// 从哪来回哪去
    			moveLeft = !moveLeft;
    		}
    		
    		// 启动自己主动滚动
    		mScrollRunnable.startScroll(moveLeft);
    	}
    
    	private class ScrollRunnable implements Runnable {
    		// 滚动辅助类,提供起始位置,移动偏移。移动总时间。能够获取每次滚动距离
    		private Scroller mScroller = new Scroller(getContext());
    		
    		@Override
    		public void run() {
    			final Scroller scroller = mScroller;
    			// 计算滚动偏移,返回能否够接着滚动
    			boolean more = scroller.computeScrollOffset();
    			// 计算后获取须要滚动到的位置
    			final int x = scroller.getCurrX();
    			
    			if (more) {
    				// 与手动滚动调用的方法同样
    				scrollIfNeed(x);
    				// 当前子线程已经运行完,可是须要接着滚动
    				// 所以把当前Runnable再次加入到消息队列中
    				post(this);
    			} else {
    				// 不须要滚动
    				endScroll();
    			}
    			
    		}
    		
    		
    		private void startScroll(boolean moveLeft) {
    			// 滚动前设置初始值
    			mLastX = mRightView.getLeft();
    			
    			int dx = 0;
    			
    			// 计算移动总距离
    			if (moveLeft) {
    				// 当前到左视图左側边界距离
    				dx = mLeftView.getLeft() - mRightView.getLeft();
    			} else {
    				// 到右側边界
    				dx = mLeftView.getRight() - mRightView.getLeft();
    			}
    			
    			// 開始滚动
    			mScroller.startScroll(mRightView.getLeft(), 0, dx, 0, 300);
    			// 把当前Runnable加入到消息队列中
    			post(this);
    		}
    		
    		private void endScroll() {
    			// 从消息队列中把当前Runnable删除,即停止滚动
    			removeCallbacks(this);
    		}
    		
    	}
    }
    

    3.CustomBaseAdapter

    package loveworld.slidingmenu;
    
    import java.util.ArrayList;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    /**
     * 
     * getView第一个參数position从0開始
     * 
     * date: 2011-11-10
     * 
     */
    public class CustomBaseAdapter extends BaseAdapter
    {
    
        private Context mContext;
        private ArrayList<String> mArrayList;
        private LayoutInflater mLayoutInflater;
    
        public CustomBaseAdapter(Context context, ArrayList<String> pData)
        {
            mContext = context;
            mArrayList = pData;
    
            mLayoutInflater = LayoutInflater.from(mContext);
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
    
            // 常见的优化ViewHolder
            ViewHolder viewHolder = null;
            if (null == convertView)
            {
                convertView = mLayoutInflater.inflate(R.layout.listview_item, null);
    
                viewHolder = new ViewHolder();
                viewHolder.content = (TextView) convertView
                        .findViewById(R.id.content);
                viewHolder.contentIcon = (ImageView) convertView
                        .findViewById(R.id.content_icon);
    
                convertView.setTag(viewHolder);
            }
            else
            {
                viewHolder = (ViewHolder) convertView.getTag();
            }
    
            // 获取数据
            viewHolder.content.setText(mArrayList.get(position));
            viewHolder.contentIcon.setImageResource(R.drawable.ic_launcher);
    
            return convertView;
        }
    
        @Override
        public int getCount()
        {
            if (null != mArrayList)
            {
                return mArrayList.size();
            }
            else
            {
                return 0;
            }
        }
    
        @Override
        public Object getItem(int position)
        {
            if (null != mArrayList && position < mArrayList.size())
            {
                return mArrayList.get(position);
            }
            else
            {
                return null;
            }
        }
    
        @Override
        public long getItemId(int position)
        {
            return position;
        }
    
        private class ViewHolder
        {
            TextView content;
            ImageView contentIcon;
        }
    
    }
    

    4.listview_item

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/list_item_selector"
        android:orientation="horizontal" >
    
        <ImageView
            android:id="@+id/content_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"/>
    
        <TextView
            android:id="@+id/content"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center"
            android:layout_marginLeft="10dip"
            android:textColor="@color/content_color" />
    
    </LinearLayout>


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    在仅有的一次生命里活出自己最大的可能
    每个人都渴望赞美
    历练领导力的八字要诀
    爱情语录
    Ps
    别跟我要钱,我是教授
    改变人生的五个问题
    纪晓岚妙用口才
    智慧和智商
    经典
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4806921.html
Copyright © 2011-2022 走看看