从来好事天生俭,自古瓜儿苦后甜。这篇文章主要讲述Android-自定义仿QQ列表Item滑动相关的知识,希望能为你提供帮助。
效果图:
文章图片
布局中去指定自定义FrameLayout:
< !-- 自定义仿QQ列表Item滑动 --> < view.custom.shangguigucustomview.MyCustomFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="80dp" android:orientation="vertical" tools:context=".ShangGuiguTestActivity" android:background="@android:color/darker_gray"> < TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="80dp" android:background="@android:color/white" android:textColor="@android:color/black" android:textSize="20dp" android:text="你有一条消息未读" android:gravity="center" android:drawableLeft="@mipmap/ic_launcher_round" android:paddingRight="40dp" /> < TextView android:id="@+id/tv_menu" android:layout_width="wrap_content" android:layout_height="80dp" android:background="@android:color/holo_orange_dark" android:textColor="#f00000" android:textSize="20dp" android:text="删除" android:gravity="center" android:paddingLeft="30dp" android:paddingRight="30dp" /> < /view.custom.shangguigucustomview.MyCustomFrameLayout>
自定义FrameLayout:
public class MyCustomFrameLayout extends FrameLayout { // 继承于FrameLayout属于继承ViewGroup,因为它包含了孩子private static final String TAG = MyCustomFrameLayout.class.getSimpleName(); /** * 拿到两个控件的宽和三个的高 * @param context * @param attrs */ private int myHeigth; // 统一的高度 private int myContentWidth; // 中间内容TextView的宽度 private int myMenuWidth; // 菜单的宽度private Scroller scroller; public MyCustomFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); scroller = new Scroller(context); }private View tvContent; private View tvMenu; /** * 当布局加载完成?后就会回调此方法 */ @Override protected void onFinishInflate() { super.onFinishInflate(); tvContent = getChildAt(0); // 拿到第一个孩子 tvMenu = getChildAt(1); // 得到第二个孩子 }/** * 测量两个孩子的高宽 * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); myContentWidth = tvContent.getMeasuredWidth(); // 等价于getMeasuredWidth(); 因为这个是后去父控件的宽度,父控件和这个孩子控件宽度是一样的 myHeigth = getMeasuredHeight(); myMenuWidth = tvMenu.getMeasuredWidth(); }/** * 为何不让实现者强制重写,应该在FrameLayout中已经重写过了 * @param changed * @param left * @param top * @param right * @param bottom */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // 指定位置 tvContent.layout(0, 0, myContentWidth, myHeigth); tvMenu.layout(myContentWidth, 0 , myContentWidth + myMenuWidth, myHeigth); }private float startX; private int x; @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: startX =event.getX(); break; case MotionEvent.ACTION_UP: float upEnd = event.getX(); float thisUp = upEnd; // float myx = getScrollX() - thisUp; if (getScrollX() > myMenuWidth / 2) { // x = myMenuWidth; openM(); } else { // x = 0; closeM(); } /*invalidate(); scroller.startScroll(getScrollX(), getScrollY(), x, Math.abs(1000)); */ // scrollTo(x, getScrollY()); break; case MotionEvent.ACTION_MOVE: int endX = (int) event.getX(); int thisX = (int) (endX - startX); int scrollX = getScrollX(); Log.i(TAG, "> > > > > scrollX" + scrollX); x =scrollX - thisX; // 非法值的屏蔽 if (x < 0) { x = 0; } else if (x > myMenuWidth) { x = myMenuWidth; }scrollTo(x, getScrollY()); startX = event.getX(); break; default: break; } return true; }private void openM() { invalidate(); int dx = myMenuWidth - getScrollX(); scroller.startScroll(getScrollX(), getScrollY(), dx, Math.abs(1000)); }private void closeM() { invalidate(); int dx = 0 - getScrollX(); scroller.startScroll(getScrollX(), getScrollY(), dx, Math.abs(1000)); }@Override public void computeScroll() { super.computeScroll(); if (scroller.computeScrollOffset()) { int currX = scroller.getCurrX(); scrollTo(currX, 0); invalidate(); } } }
【Android-自定义仿QQ列表Item滑动】
推荐阅读
- Spring源码解析 – AnnotationConfigApplicationContext容器创建过程
- 迈向高阶(优秀Android程序员必知必会的网络基础)
- Android PDA扫描枪广播接搜条码并使用
- 高德定位腾讯定位在APP上无法开启定位权限的解决方案
- Android开发资源收集
- Android View 的事件分发原理解析
- mybatis学习 十六 auto_mapping实现连表查询
- Android Studio中进行单元测试
- YII开发第一个例子