背景视图在滑动功能中默认显示

问题描述 投票:0回答:2

我正在尝试在我的应用中实现滑动功能。滑动功能本身运行良好。但是,应用程序始终默认显示背景视图(有点像刮刮赢),看看这个:

(Qazxswpoi)

我尝试用XML格式化http://i.imgur.com/NTGcguT.pngforeground几乎无处不在,同时在java中引用它们,在backgroundonChildDraw和所有其他方法中引用它们,但是根本没有运气。

一旦我触摸卡进行滑动,该功能就能正常工作(图中的卡2)。如果我松开滑动并将卡片恢复到默认位置,它将正常工作(图片中的卡片3和5)。一旦再次创建活动,所有卡都将进入默认的蓝色背景(图片中的1,4和6卡)

编辑:顺便说一句,卡片x,y,z指的是他们在屏幕上的位置而不是他们的内容,只是碰巧他们都是1个数字,因为我尝试尽可能快地让他们继续测试

这是我的相关代码:

XML文件:

onChildDrawOver

在MyHolder.JAVA中定义:

<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:descendantFocusability="blocksDescendants"
>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="0dp"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
android:layout_height="match_parent"
android:longClickable="true"
android:contextClickable="true">

<RelativeLayout
    android:id="@+id/view_foreground"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--Foreground elements here-->

</RelativeLayout>

<RelativeLayout
    android:id="@+id/view_background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    >

    <!--Background elements here-->
</RelativeLayout>

</android.support.v7.widget.CardView>
</FrameLayout>

这是家庭活动(您在屏幕截图中看到的那个):

    public RelativeLayout viewBackground, viewForeground;
    ... 
    viewBackground = (RelativeLayout)itemView.findViewById(R.id.view_background);
    viewForeground = (RelativeLayout)itemView.findViewById(R.id.view_foreground);
    delTxt = (TextView) itemView.findViewById(R.id.delBackground);

编辑:找到解决方案,我只是翻转XML文件中的背景和前景,所以前景变为第二,然后给前景一个白色背景颜色。

java android swipe
2个回答
0
投票

这个问题可能是由ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { //some stuff } @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final View foregroundView = ((MyHolder)viewHolder).viewForeground; drawBackground(viewHolder, dX, actionState); if (viewHolder.getAdapterPosition() == -1) { return; } getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive); } @Override public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final View foregroundView = ((MyHolder)viewHolder).viewForeground; drawBackground(viewHolder, dX, actionState); getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive); } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder){ final View backgroundView = ((MyHolder)viewHolder).viewBackground; final View foregroundView = ((MyHolder)viewHolder).viewForeground; backgroundView.setRight(0); getDefaultUIUtil().clearView(foregroundView); } private void drawBackground(RecyclerView.ViewHolder viewHolder, float dX, int actionState) { final View backgroundView = ((MyHolder)viewHolder).viewBackground; if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { //noinspection NumericCastThatLosesPrecision backgroundView.setRight((int) Math.max(dX, 0)); } } RecyclerView.notifyDatasetChange()的无效引起的。当RecyclerView的UI更新时,它可能会创建新的RecyclerView,其视图将成为默认值。或者当一个默认的ViewHolder(例如:你的照片中的卡片6)被回收并在位置1(你的照片中的卡片2)中重复使用时也会导致你的问题。 因此,您应该在手势回调中保存View的状态,并在ViewHolder中恢复View的状态


0
投票

我在下面写一个演示。如果不编写代码来恢复自定义视图,则滚动Adapter.onBindViewHolder()时自定义视图的行为可能是错误的。

RecyclerView活动:

RecyclerView

CustomView:

public class RecyclerViewActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private Adapter mAdapter;
    private List<ViewStatus> mViewStatuses;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        initData();
        initAdapter();
        LinearLayoutManager manager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(manager);
    }

    private void initData() {
        mViewStatuses = new ArrayList<>();
        int i = 0;
        while (i < 100) {
            ViewStatus temp = new ViewStatus();
            temp.isBeanTouched = false;
            temp.text = String.valueOf(i);
            mViewStatuses.add(temp);
            i++;
        }
    }

    private void initAdapter() {
        mAdapter = new Adapter();
        mRecyclerView.setAdapter(mAdapter);
    }


    class Adapter extends RecyclerView.Adapter<ViewHolder> {
        LayoutInflater mInflater = LayoutInflater.from(RecyclerViewActivity.this);

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View holderView = mInflater.inflate(R.layout.item_recycler_view, parent, false);
            return new ViewHolder(holderView);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.onBind(position);
        }

        public ViewStatus getItem(int position) {
            return mViewStatuses.get(position);
        }

        @Override
        public int getItemCount() {
            return mViewStatuses.size();
        }
    }

    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView currentPosTv;
        TextView prePosTv;
        CustomView mCustomView;
        ViewStatus mViewStatus;

        public ViewHolder(View itemView) {
            super(itemView);
            currentPosTv = (TextView) itemView.findViewById(R.id.tv_current_pos);
            prePosTv = (TextView) itemView.findViewById(R.id.tv_pre_pos);
            mCustomView = (CustomView) itemView.findViewById(R.id.custom_view);
        }

        public void onBind(int position) {
            mViewStatus = mAdapter.getItem(position);
            // if holder is recycled and reused, then save the pre position in prePosTv
            prePosTv.setText("pre position: " + currentPosTv.getText());
            currentPosTv.setText("current position: " + mViewStatus.text);
            itemView.setOnClickListener(this);
            //if do not add code blow to resume customView, then the customView's behavior may be wrong when scroll RecyclerView
//            mCustomView.setSelect(mViewStatus.isBeanTouched);
        }

        @Override
        public void onClick(View v) {
            //save the view status
            mViewStatus.isBeanTouched = !mViewStatus.isBeanTouched;
            mCustomView.setSelect(mViewStatus.isBeanTouched);
        }
    }

    class ViewStatus {
        boolean isBeanTouched = false;
        String text = "";
    }
}

activity_recycler_view.xml:

public class CustomView extends View {

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setSelect(boolean select) {
        if (select) {
            setBackgroundColor(Color.RED);
        } else {
            setBackgroundColor(Color.WHITE);
        }
    }
}

item_recycler_view

<?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="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>
© www.soinside.com 2019 - 2024. All rights reserved.