自定义Veiw的实践(一)---一个简易侧滑菜单的实现

来源:互联网 发布:windows官方商城 编辑:程序博客网 时间:2024/05/16 07:52

转载请注明出处:From李诗雨---http://blog.csdn.net/cjm2484836553/article/details/71063040

不诗意的女程序猿不是好厨师~

在前面的自定义View一、二、三 三篇文章中,我们基本涉及到了关于自定义View的所有知识点。基础有了,重点看了,难点沾了,思路也明朗了。那我们不来动手写写,是不是觉得太过分了?所以今天我们就先来实现一个简易的侧滑菜单吧,真的是超简单。


先看一下今天我们要完成的简易侧滑菜单效果的效果。


功能概括:

可以通过左右滑动对菜单进行拖拽,

可以通过点击具体的按键实现菜单的自动打开与关闭。


现在,就让我们完全按照第三篇文章整理出来的思路来一步一步进行:

1.首先考虑要继承什么

这里我们继承FrameLayout

public class MySlideLayout extends FrameLayout {    public MySlideLayout(Context context, AttributeSet attrs) {        super(context, attrs);    }}


2.考虑自定义属性

这里我们不需要,所以略过即可~


3.重写其相关的回调方法

3.1 重写onFinishInflate()方法,来得到菜单视图。这里我们默认第二个孩子是侧滑菜单。

@Override    protected void onFinishInflate() {        super.onFinishInflate();        menuView = getChildAt(1);    }



3.2 重写onMeasure()方法: 得到菜单视图的宽高
@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        menuWidth = menuView.getMeasuredWidth();        menuHeight = menuView.getMeasuredHeight();    }


3.3 重写OnLayout()方法: 对菜单进行重新布局
@Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        menuView.layout(-menuWidth, 0, 0, menuHeight);    }



4.考虑滑动

这里我们需要实现可拖动的菜单,所以是涉及到滑动的。

所以我们需要

4.1 重写onTouchEvent()方法来响应用户的操作:

       在move时来计算事件的偏移, 对当前布局进行滚动

       在up时, 根据布局来的偏移量, 来判断是打开/关闭菜单

 @Override    public boolean onTouchEvent(MotionEvent event) {        int eventX = (int) event.getRawX();        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN :                lastX = eventX;                break;            case MotionEvent.ACTION_MOVE :                int dx = eventX-lastX;                int scrollX = getScrollX()-dx;                //限制scrollX : [-menuWidth, 0]                if(scrollX<-menuWidth) {                    scrollX = -menuWidth;                } else if(scrollX>0) {                    scrollX = 0;                }                scrollTo(scrollX, getScrollY());                lastX = eventX;                break;            case MotionEvent.ACTION_UP :                //得到布局的偏移量                int totalScrollX = getScrollX();                if(totalScrollX<=-menuWidth/2) {                    openMenu();                } else {                    closeMenu();                }                break;        }        return true;    }


4.2 使用Scoller实现平滑打开/关闭

4.2.1 平滑的打开菜单

private void openMenu() {        scroller.startScroll(getScrollX(), getScrollY(), -menuWidth-getScrollX(), -getScrollY());        invalidate();        isOpen = true;    }

4.2.2 平滑的关闭菜单

private void closeMenu() {scroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), -getScrollY());invalidate();isOpen = false;}



4.3 实现弹性滑动

Scroller本身是无法让View弹性滑动的,它需要和View的computeScroll方法配合使用才能共同完成

所以这里我们还需要重写computeScroll()方法

@Override    public void computeScroll() {        super.computeScroll();        if(scroller.computeScrollOffset()) {            scrollTo(scroller.getCurrX(), scroller.getCurrY());            invalidate();        }    }


4.4 最后我们再提供一个可以切换状态的方法,以方便外界调用

public void switchState() {        if (isOpen) {            closeMenu();        } else {            openMenu();        }    }


5.考虑滑动冲突

暂时还不涉及,暂不考虑~


6.使用自定义的View

经过以上简单几步,我们的自定义View就基本完成了,接下来就可以开始使用了。

MainActivity的布局中使用自定义View:

<com.chrismas.shiyu.lsy_custom_view.MySlideLayout android:id="@+id/ml_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:android="http://schemas.android.com/apk/res/android">    <include layout="@layout/main_content" />    <include layout="@layout/main_menu" /></com.chrismas.shiyu.lsy_custom_view.MySlideLayout>

详细布局见源码


MainActivity的代码:

public class MainActivity extends AppCompatActivity {    private TextView tv_answer;    private MySlideLayout ml_main;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        tv_answer = (TextView) findViewById(R.id.tv_answer);        ml_main = (MySlideLayout) findViewById(R.id.ml_main);        //点击图标切换打开、关闭的状态        findViewById(R.id.main_back).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                ml_main.switchState();            }        });    }    //点击左侧item的点击事件的响应    public void clickMenuItem(View v) {        TextView textiew = (TextView) v;        String answer = "抱歉,主人没有给出明确答案";        tv_answer.setText(answer);        ml_main.switchState();    }}


这就行了?恩!这样一个简易的侧滑菜单就实现了。话说会不会太简单朴素了,你们是不是都不屑于下手了?

这个,别急,学习也要循序渐进的吗?后期还会有很多比较复杂的自定义View的实践的,奈何五一假期过完了,只能往后放放再增加新篇了。



源码下载:点击下载













0 0