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

转载请注明出处: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的实践的,奈何五一假期过完了,只能往后放放再增加新篇了。



源码下载:点击下载













猜你喜欢

转载自blog.csdn.net/cjm2484836553/article/details/71063040