利用ViewDragHelper做滑动效果,侧滑的布局整体是一个LinearLayout,里面包含3个TextView分别是,已读,删除,置顶。 运行之后,LinearLayout布局只出现已读和删除这2个TextView。


public class SlideMenuView extends ViewGroup {
private static final String TAG = "SlideMenuView";
private int mFunction;
private View mContentView;
private TextView mRead;
private TextView mDelete;
private TextView mTop;
private int DEFAULT_LEFT = 0;
private ViewDragHelper mViewDragHelper;
private int mWidthSize;
private LinearLayout mLinearLayout;
public int getDEFAULT_LEFT() {
return DEFAULT_LEFT;
}
public void setDEFAULT_LEFT(int DEFAULT_LEFT) {
this.DEFAULT_LEFT = DEFAULT_LEFT;
}
public SlideMenuView(Context context) {
this(context, null);
}
public SlideMenuView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlideMenuView);
mFunction = ta.getInt(R.styleable.SlideMenuView_function, 0);
Log.d(TAG, "function --> " + mFunction);
ta.recycle();
mViewDragHelper = ViewDragHelper.create(this, new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(@NonNull View child, int pointerId) {
Log.d(TAG, "child " + child.getMeasuredWidth());
Log.d(TAG, "pointerId " + pointerId);
return child == mContentView;
//|| child == mLinearLayout
}
@Override
public void onViewCaptured(@NonNull View capturedChild, int activePointerId) {
super.onViewCaptured(capturedChild, activePointerId);
Log.d(TAG, "capturedChild " + capturedChild);
Log.d(TAG, "activePointerId " + activePointerId);
}
@Override
public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
//可以设置移动范围,不限制就无限
Log.d(TAG, "child " + child);
Log.d(TAG, "left " + left);
Log.d(TAG, "dx " + dx);
if (left <= -(mContentView.getMeasuredWidth() * 3 / 4)) {
//Log.d(TAG, "small left " + left);
//Log.d(TAG, "-(3 / 4 * mWidthSize) " + -(mContentView.getMeasuredWidth() * 3 / 4));
//Log.d(TAG, "mContentView.getMeasuredWidth() " + mContentView.getMeasuredWidth());
return left = -(mContentView.getMeasuredWidth() * 3 / 4);
}
if (left > 0) {
return left = 0;
}
return left;
}
@Override
public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
invalidate();
//super.onViewPositionChanged(changedView, left, top, dx, dy);
Log.d(TAG, "onViewPositionChanged -- changedView " + changedView);
Log.d(TAG, "onViewPositionChanged -- left " + left);
Log.d(TAG, "onViewPositionChanged -- top " + top);
Log.d(TAG, "onViewPositionChanged -- dx " + dx);
Log.d(TAG, "onViewPositionChanged -- dy " + dy);
if (changedView == mContentView) {
mContentView.layout(left, 0, left + mContentView.getMeasuredWidth(), mContentView.getMeasuredHeight());
Log.d(TAG, "mContentView.getMeasuredWidth() " + mContentView.getMeasuredWidth());
Log.d(TAG, "left + mContentView.getMeasuredWidth() " + left + mContentView.getMeasuredWidth());
mLinearLayout.layout(left + mContentView.getMeasuredWidth(), 0, left + mContentView.getMeasuredWidth() + mLinearLayout.getMeasuredWidth(), mLinearLayout.getMeasuredHeight());
}
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(TAG, "event " + event.getAction());
mViewDragHelper.processTouchEvent(event);
return true;//true才能监听其他手势
//return super.onTouchEvent(event);
}
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
mViewDragHelper.shouldInterceptTouchEvent(event);
return true;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//构造方法获取不了孩子个数
int childCount = getChildCount();
Log.d(TAG, "childCount --> " + childCount);
//加个判断只能有一个孩子
if (childCount > 1) {
throw new IllegalArgumentException("no more than one child");
}
//内容部分
mContentView = getChildAt(0);
//根据属性继续添加子View
mLinearLayout = new LinearLayout(getContext());
mLinearLayout.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
mLinearLayout.setLayoutParams(layoutParams);
mLinearLayout.setGravity(Gravity.CENTER);
String s[] = {"已读", "删除", "置顶"};
for (int i = 0; i < 3; i++) {
TextView tv = new TextView(getContext());
tv.setGravity(Gravity.CENTER);
tv.setTextColor(getResources().getColor(R.color.mainColor));
tv.setBackgroundColor(getResources().getColor(R.color.text_grey));
tv.setText(s[i]);
mLinearLayout.addView(tv);
}
addView(mLinearLayout);
/* mRead = new TextView(getContext());
mRead.setGravity(Gravity.CENTER);
mRead.setTextColor(getResources().getColor(R.color.mainColor));
mRead.setBackgroundColor(getResources().getColor(R.color.text_grey));
mRead.setText("已读");
addView(mRead);
mDelete = new TextView(getContext());
mDelete.setGravity(Gravity.CENTER);
mDelete.setTextColor(getResources().getColor(R.color.mainColor));
mDelete.setBackgroundColor(getResources().getColor(R.color.colorAccent));
mDelete.setText("删除");
addView(mDelete);
mTop = new TextView(getContext());
mTop.setGravity(Gravity.CENTER);
mTop.setTextColor(getResources().getColor(R.color.mainColor));
mTop.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
mTop.setText("置顶");
addView(mTop);*/
int afterCount = getChildCount();
Log.d(TAG, "afterCount --> " + afterCount);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int left = DEFAULT_LEFT;
int top = 0;
int bottom = top + mContentView.getMeasuredHeight();
//摆放内容
// mContentView.layout(left, top, right, bottom);
Log.d(TAG, "childCount layout --> " + getChildCount());
for (int i = 0; i < getChildCount(); i++) {
View childAt = getChildAt(i);
Log.d(TAG, "childAt Height --> " + childAt.getMeasuredHeight());
Log.d(TAG, "childAt Width --> " + childAt.getMeasuredWidth());
int right = left + childAt.getMeasuredWidth();
Log.d(TAG, "right --> " + right);
childAt.layout(left, top, right, bottom);
left = right;
}
Log.d(TAG, "left " + left);
//LinearLayout第一个子view左边等于内容部分的右边
int childLeft = mContentView.getMeasuredWidth();
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
View childAt = mLinearLayout.getChildAt(i);
int childRight = childLeft + childAt.getMeasuredWidth();
Log.d(TAG, "childLeft " + childLeft);
Log.d(TAG, "childRight " + childRight);
childAt.layout(childLeft, 0, childRight, bottom);
childLeft = childRight;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
mWidthSize = MeasureSpec.getSize(widthMeasureSpec);
Log.d(TAG, "widthMeasureSpec " + widthMeasureSpec);
Log.d(TAG, "widthSize " + mWidthSize);
//测量第一个孩子,内容部分
//宽度跟父控件一样,高度有3种情况
//getMeasuredWidth测量不了我们提前放进去的TextView大小,getLayoutParams可以,要先测量一下
int measuredWidth = mContentView.getMeasuredWidth();
int measuredHeight = mContentView.getMeasuredHeight();
Log.d(TAG, "mContentView-Width " + measuredWidth);
Log.d(TAG, "mContentView-Height " + measuredHeight);
LayoutParams layoutParams = mContentView.getLayoutParams();
int height = layoutParams.height;
int width = layoutParams.width;
Log.d(TAG, "height " + height);
Log.d(TAG, "width " + width);
int contentHeightMeasureSpec;
if (height == LayoutParams.MATCH_PARENT) {
contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
} else if (height == LayoutParams.WRAP_CONTENT) {
contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
} else {
//指定大小
contentHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
//如果最外面布局不是LinearLayout view会越界,居中显示能看出,但是活动的时候还是宽度会越界,应该是测量问题,与父控件布局无关
Log.d(TAG, "measure widthMeasureSpec " + widthMeasureSpec);
mContentView.measure(widthMeasureSpec, contentHeightMeasureSpec);
//拿到内容部分,测量高度
int contentMeasureHeight = mContentView.getMeasuredHeight();
//测量编辑部分,宽度3/4,高度跟内容部分一样,就是提前添加的TextView,要设置模式
mLinearLayout.measure(MeasureSpec.makeMeasureSpec(mWidthSize * 3 / 4, MeasureSpec.EXACTLY),
contentHeightMeasureSpec);
Log.d(TAG, "mLinearLayout.getMeasuredWidth() * 1 / 3 " + mLinearLayout.getMeasuredWidth() * 1 / 3);
for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
View childAt = mLinearLayout.getChildAt(i);
childAt.measure(MeasureSpec.makeMeasureSpec(mLinearLayout.getMeasuredWidth() * 1 / 3, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mContentView.getMeasuredHeight(), MeasureSpec.EXACTLY));
}
/* mRead.measure(MeasureSpec.makeMeasureSpec(mWidthSize * 1 / 4, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(contentMeasureHeight, MeasureSpec.EXACTLY));
mTop.measure(MeasureSpec.makeMeasureSpec(mWidthSize * 1 / 4, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(contentMeasureHeight, MeasureSpec.EXACTLY));
mDelete.measure(MeasureSpec.makeMeasureSpec(mWidthSize * 1 / 4, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(contentMeasureHeight, MeasureSpec.EXACTLY));*/
//测量自己
//宽度是前面的总和,高度和内容一样
//测量自己不需要模式
setMeasuredDimension(mWidthSize + mWidthSize * 3 / 4, contentMeasureHeight);
}
}
或者你看下一节课视频,明天之前更新。
用LayoutInspector查看一下不就知道了吗?