我有Adapter
扩展RecyclerView.Adapter
。每一行适配器都是一个自定义的FrameLayout,实现了GestureDetector。 FrameLayout xml
文件有2个RelativeLayout
。
在此FrameLayout
中,我将X和Y位置重定向到前景中的RelativeLayout
。
在每个RelativeLayout
我都有一个setOnClickListener
。这是因为如果用户单击前景中的RelativeLayout
,则会启动activity
。如果用户滚动前者,则可以单击后者。
我面临的是:
在这些布局上实施setOnClickListener
我丢失了自定义FrameLayout
的视图滚动功能。我需要滚动功能并为每个视图clickListener
。
这是我的xml
file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/background_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/work_order_deleted_item_background_color">
...
</RelativeLayout>
<RelativeLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:visibility="invisible"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
...
</RelativeLayout>
</FrameLayout>
我的自定义FrameLayout:
public class SwipeView extends FrameLayout implements GestureDetector.OnGestureListener{
private RelativeLayout container;
private RelativeLayout backgroundContainer;
private GestureDetector detector;
private float posX;
private float posY;
private float lastTouchX;
private float lastTouchY;
private float xLimit;
private int mActivePointerId;
public SwipeView(@NonNull Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.adapter_work_order, this);
initViews(context, null);
xLimit = 200.0f;
mActivePointerId = INVALID_POINTER_ID;
detector = new GestureDetector(this);
}
public SwipeView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initViews(context, attrs);
xLimit = 200.0f;
mActivePointerId = INVALID_POINTER_ID;
detector = new GestureDetector(this);
}
public SwipeView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initViews(context, attrs);
xLimit = 200.0f;
mActivePointerId = INVALID_POINTER_ID;
detector = new GestureDetector(this);
}
private void initViews(Context context, AttributeSet attrs){
this.container = this.findViewById(R.id.container);
this.backgroundContainer = this.findViewById(R.id.background_container);
this.checkboxDownload = this.findViewById(R.id.checkbox_download);
this.textviewWo = this.findViewById(R.id.textview_wo);
this.downloadedWo = this.findViewById(R.id.textview_downloaded_wo);
this.textviewTime = this.findViewById(R.id.textview_time);
this.textviewField1 = this.findViewById(R.id.textview_field_1);
this.textviewField2 = this.findViewById(R.id.textview_field_2);
this.textviewField3 = this.findViewById(R.id.textview_field_3);
this.deleteLabel = this.backgroundContainer.findViewById(R.id.delete_wo);
}
@Override
public boolean onTouchEvent(MotionEvent event){
final int action = MotionEventCompat.getActionMasked(event);
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
// Remember where we started (for dragging)
lastTouchX = x;
lastTouchY = y;
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(event, 0);
if(x > container.getRight() + container.getX()){
Log.e("ERROR", "TOUCHED OUTSIDE");
}
else {
Log.e("ERROR", "TOUCHED INSIDE: ");
}
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex = MotionEventCompat.findPointerIndex(event, mActivePointerId);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
// Calculate the distance moved
final float dx = x - lastTouchX;
final float dy = y - lastTouchY;
posX += dx;
posY += dy;
if(posX <= -xLimit){
posX -= dx;
}
if(posX > 0.0f){
posX = 0.0f;
}
invalidate();
// Remember this touch position for the next move event
lastTouchX = x;
lastTouchY = y;
container.setX(posX);
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
}
return true;
}
@Override
public boolean onDown(MotionEvent motionEvent) {
return true;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return true;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return true;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float velocityX, float velocityY) {
return true;
}
}
此代码位于我的适配器中:
holder.container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//onItemClickListener.onItemClick(workOrder);
Log.e("ERROR", "FOREGROUND CLICKED");
}
});
holder.backgroundContainer.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Log.e("ERROR", "BACKGROUND CLICKED");
}
});
最后,这是我的活动中的代码:
((MyAdapter) recyclerview.getAdapter())
.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
@Override
public void onItemClick(Item item) {
if(!presenter.getDownloadAvailability()) {
...
}
}
});
答案 0 :(得分:0)
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:fillViewport="false">
<RelativeLayout
android:id="@+id/background_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/work_order_deleted_item_background_color">
...
</RelativeLayout>
</ScrollView>