效果
自定义ViewGroup
package com.example.formwork.view;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.GenericLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import com.example.formwork.R;
public class TranslateView extends FrameLayout {
private ImageView translateImg;
private TextView translateTit;
private View rootView;
public TranslateView(@NonNull Context context) {
super(context);
}
public TranslateView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public TranslateView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private int width = 250;
private int min = 250;
private int max = 600;
private Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
width += 10;
if (width < max) {
handler.sendEmptyMessageDelayed(1, 10);
requestLayout();
} else {
translateTit.setVisibility(View.VISIBLE);
}
break;
case 2:
width -= 10;
if (width > min) {
translateTit.setVisibility(View.INVISIBLE);
handler.sendEmptyMessageDelayed(2, 10);
requestLayout();
}
break;
}
}
};
private void init(Context context, AttributeSet attrs) {
rootView = LayoutInflater.from(context).inflate(R.layout.translate_view, this);
translateImg = (ImageView) rootView.findViewById(R.id.translate_img);
translateTit = (TextView) rootView.findViewById(R.id.translate_tit);
translateImg.setOnClickListener(view -> {
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(1, 10);
});
translateTit.setOnClickListener(view -> {
Toast.makeText(context, "这是文字", Toast.LENGTH_SHORT).show();
});
LifecycleOwner lifecycleOwner = (LifecycleOwner) context;
lifecycleOwner.getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
Log.d("LQS", "==页面已经销毁,收到销毁事件");
handler.removeCallbacksAndMessages(null);
}
}
});
}
private int lastY, lastX;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) ev.getRawX();
lastY = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(ev.getRawX() - lastX) > 10 || (Math.abs(ev.getRawY() - lastY) > 10)) {
lastX = (int) ev.getRawX();
lastY = (int) ev.getRawY();
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
int newX = (int) event.getRawX();
int newY = (int) event.getRawY();
int dx = newX - lastX;
int dy = newY - lastY;
TranslateView.this.layout(TranslateView.this.getLeft()+dx,TranslateView.this.getTop()+dy,
TranslateView.this.getRight()+dx,TranslateView.this.getBottom()+dy);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(TranslateView.this.width,TranslateView.this.getHeight());
layoutParams.leftMargin = TranslateView.this.getLeft();
layoutParams.topMargin = TranslateView.this.getTop();
layoutParams.rightMargin = TranslateView.this.getRight();
layoutParams.bottomMargin = TranslateView.this.getBottom();
layoutParams.setMargins(TranslateView.this.getLeft(),TranslateView.this.getTop(),0,0);
TranslateView.this.setLayoutParams(layoutParams);
lastX = newX;
lastY = newY;
}
return true;
}
private int listY;
public void isResetWidth(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
listY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if (event.getRawY() < listY) {
resetWidth(event);
}
break;
}
}
private void resetWidth(MotionEvent event) {
if (isTouchInCurrentView(event)) {
Log.d("LQS", "在控件上滑动,不需要执行收缩操作");
return;
}
if (handler.hasMessages(2) || width == 250) {
return;
}
handler.removeCallbacksAndMessages(null);
handler.sendEmptyMessageDelayed(2, 10);
}
private boolean isTouchInCurrentView(MotionEvent event) {
int eventRawX = (int) event.getRawX();
int eventRawY = (int) event.getRawY();
int[] viewLoc = new int[2];
getLocationOnScreen(viewLoc);
int left = viewLoc[0];
int top = viewLoc[1];
int right = left + getMeasuredWidth();
int bottom = top + getMeasuredHeight();
boolean isInView = eventRawX >= left && eventRawX <= right &&
eventRawY >= top && eventRawY <= bottom;
return isInView;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(width, MeasureSpec.getSize(heightMeasureSpec));
}
}
Activity
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
translate.isResetWidth(ev);
return super.dispatchTouchEvent(ev);
}