Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 側拉新聞菜單

側拉新聞菜單

編輯:關於Android編程

功能描述

菜單分左右兩側,整體可以滑動,效果如下
左側菜單
右側詳細頁面

功能分析

widthMeasureSpec:期望值

組成: 32位的010101010101011010101組成 頭2位:代表的是模式
UNSPECIFIED: 不確定,隨意 EXACTLY:精確的 AT_MOST:最大的 後30位:數值

scrollTo:

移動的是手機的屏幕 標准移動

scrollBy:

移動的是手機的屏幕 增量移動

Scroller: 用來模擬數據變化

computeScroll()

ViewDragHelper:

用來分析touch事件的工具類

使用步驟

獲取實例

ViewDragHelper helper =ViewDragHelper.create(ViewGroup, CallBack);

touch分析和監聽

    @Override
public boolean onTouchEvent(MotionEvent event) {
mHelper.processTouchEvent(event);
return true;
}

實現自己的callBack

touch:

down
tryCaptureView() move
clampViewPositionHorizontal:水平移動的回調 up

代碼實現

頁面布局
activity_main.xml



    
        
        
        
        
    

左菜單(left.xml)



    

        

        

        

        

        

        

        

        

    

右邊主界面(content.xml)



    
        
        
        
    
    


drawable目錄下tab_bg.xml選擇器


    
    
styles.xml
SlidingMenu.java
package com.cdw.slidingmenu;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;

/**
 * Created by dongwei on 2016/8/2.
 */
public class SlidingMenu extends ViewGroup {
    private View mLeftView;
    private View mContentView;
    private int mLeftWidth;
    private float mDownX;
    private float mDownY;
    private Scroller mScroller;
    private boolean isLeftShow = false;

    public SlidingMenu(Context context) {
        this(context, null);
    }

    public SlidingMenu(Context context, AttributeSet attrs) {
        super(context, attrs);

        mScroller = new Scroller(context);
    }

    @Override
    protected void onFinishInflate() {
        //xml加載完成時
        mLeftView = getChildAt(0);
        mContentView = getChildAt(1);

        LayoutParams params = mLeftView.getLayoutParams();
        mLeftWidth = params.width;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //測量孩子
        int leftWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mLeftWidth, MeasureSpec.EXACTLY);
        mLeftView.measure(leftWidthMeasureSpec, heightMeasureSpec);
        mContentView.measure(widthMeasureSpec, heightMeasureSpec);
        //設置自己的寬度和高度
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int width = mLeftView.getMeasuredWidth();
        int height = mLeftView.getMeasuredHeight();
        //給左側布局

        int lvLeft = -width;
        int lvTop = 0;
        int lvRight = 0;
        int lvBottom = height;
        mLeftView.layout(lvLeft, lvTop, lvRight, lvBottom);

        //給右側布局
        int cLeft = 0;
        int cTop = 0;
        int cRight = mContentView.getMeasuredWidth();
        int cBottom = mContentView.getMeasuredHeight();
        mContentView.layout(cLeft, cTop, cRight, cBottom);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                mDownX = ev.getX();
                mDownY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = ev.getX();
                float moveY = ev.getY();

                if (Math.abs(moveX - mDownX) > Math.abs(moveY - mDownY)){
                    //水平方向移動
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:

                break;
            default:
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = event.getX();
                float moveY = event.getY();

                int diffX = (int) (mDownX - moveX + 0.5f);

                int scrollX = getScrollX() + diffX;
                if (scrollX < 0 && scrollX < -mLeftView.getMeasuredWidth()){
                    scrollTo(-mLeftView.getMeasuredWidth(), 0);
                }else if (scrollX > 0){
                    scrollTo(0, 0);
                }else {
                    scrollBy(diffX, 0);
                }

                mDownX = moveX;
                mDownY = moveY;
                break;
            case MotionEvent.ACTION_UP:
                //判斷是打開還是關閉
                int width = mLeftView.getMeasuredWidth();
                int currentX = getScrollX();
                float middle = -width / 2f;
                switchMenu(currentX <= middle);
                break;
            default:
                break;
        }
        return true;
    }

    private void switchMenu(boolean showLeft) {
        isLeftShow = showLeft;
        int width = mLeftView.getMeasuredWidth();
        int currentX = getScrollX();
        if (!showLeft){
            //scrollTo(0, 0);

            int startX = currentX;
            int startY = 0;
            int endX = 0;
            int endY = 0;
            int dx = endX - startX;
            int dy = endY - startY;
            int duration = Math.abs(dx) * 10;
            if (duration >= 600){
                duration = 600;
            }
            //模擬數據變化
            mScroller.startScroll(startX, startY, dx, dy, duration);
        }else {
            //scrollTo(-width, 0);

            int startX = currentX;
            int startY = 0;
            int endX = -width;
            int endY = 0;
            int dx = endX - startX;
            int dy = endY - startY;
            int duration = Math.abs(dx) * 10;
            if (duration >= 600){
                duration = 600;
            }
            mScroller.startScroll(startX, startY, dx, dy, duration);
        }

        invalidate();
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()){
            //更新位置
            scrollTo(mScroller.getCurrX(), 0);
            invalidate();
        }
    }

    public void toggle(){
        switchMenu(!isLeftShow);
    }
}
mainActivity.java
package com.cdw.slidingmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private SlidingMenu menu;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        menu = (SlidingMenu) findViewById(R.id.sm);
    }

    public void clickTab(View view){
        String text = ((TextView)view).getText().toString();
        Toast.makeText(this, "點擊了" + text, Toast.LENGTH_SHORT).show();
        menu.toggle();
    }

    public void clickBack(View view){
        menu.toggle();
    }
}


項目鏈接:Android/tree/ec78b9b3d2d3bb22b51b0784d26dca18960ab01a/slidingmenu">https://github.com/ChenDongWei/Android/tree/ec78b9b3d2d3bb22b51b0784d26dca18960ab01a/slidingmenu

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved