Recyclerview reuse of View

Asked

Viewed 68 times

-1

I’m Implementing a RecyclerView as follows:

class ObjAdapter extends RecyclerView.Adapter<ObjetoHolder>{

        private RealmResults<Objeto> objetos;

        private final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
        final RealmChangeListener change = new RealmChangeListener<RealmResults<Objeto>>() {
            @Override
            public void onChange(RealmResults<Objeto> element) {
                objetos = element;
                ObjAdapter.this.notifyDataSetChanged();
            }
        };

        public ObjAdapter(){
            objetos = realm.where(Objeto.class).findAll().sort("id");
            objetos.addChangeListener(change);
        }

        @Override
        public ObjetoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new ObjetoHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter, parent, false));
        }

        @Override
        public void onBindViewHolder(ObjetoHolder holder, int position) {
            final Objeto objeto = objetos.get(position);
            holder.objName.setText(objeto.getName());
            holder.objTimestamp.setText(sdf.format(objeto.getTimestamp()));
            holder.objId.setText(objeto.getId().toString());
        }

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

    public static final class ObjetoHolder extends RecyclerView.ViewHolder {
        ObjCard cv;
        TextView objId;
        TextView objName;
        TextView objTimestamp;

        ObjetoHolder(final View view){
            super(view);
            cv = ObjCard.class.cast(view.findViewById(R.id.cv));
            objId = TextView.class.cast(view.findViewById(R.id.objId));
            objName = TextView.class.cast(view.findViewById(R.id.objName));
            objTimestamp = TextView.class.cast(view.findViewById(R.id.objTimestamp));
        }


    }

One of the elements is a ObjCard, an object I created, extending from CardView. I do it because I implement a GestureListener.

public class ObjCard extends CardView   {


    public ObjCard(Context context) {
        super(context);
        initalize();
    }
    public ObjCard(Context context, AttributeSet attrs) {
        super(context, attrs);
        initalize();
    }
    public ObjCard(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initalize();
    }
    private void initalize(){
        setOnTouchListener(new OnSwipeTouchListener(getContext()));
    }

    public class OnSwipeTouchListener implements OnTouchListener {

        private final GestureDetector gestureDetector;

        public OnSwipeTouchListener (Context ctx){
            gestureDetector = new GestureDetector(ctx, new GestureListener());
        }
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return gestureDetector.onTouchEvent(event);
        }

        private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

            private static final int SWIPE_THRESHOLD = 100;
            private static final int SWIPE_VELOCITY_THRESHOLD = 100;

            @Override
            public boolean onDown(MotionEvent e) {
                return true;
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                boolean result = false;
                try {
                    float diffY = e2.getY() - e1.getY();
                    float diffX = e2.getX() - e1.getX();
                    if (Math.abs(diffX) > Math.abs(diffY)) {
                        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                            if (diffX > 0) {
                                onSwipeRight();
                            } else {
                                onSwipeLeft();
                            }
                        }
                        result = true;
                    }
                    else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffY > 0) {
                            onSwipeBottom();
                        } else {
                            onSwipeTop();
                        }
                    }
                    result = true;

                } catch (Exception exception) {
                    exception.printStackTrace();
                }
                return result;
            }
        }

        public void onSwipeRight() {
            Log.w("[SWIPE]", "RIGHT >");
            final ImageButton deleteAction = ImageButton.class.cast(findViewById(R.id.deleteAction));
            if(deleteAction.getVisibility() == View.VISIBLE){
                final Animation _anim = AnimationUtils.loadAnimation(getContext(), R.anim.slide_out_to_right);
                deleteAction.startAnimation(_anim);
                deleteAction.setVisibility(View.GONE);
            }


        }

        public void onSwipeLeft() {
            Log.w("[SWIPE]", "< LEFT ");
            final ImageButton deleteAction = ImageButton.class.cast(findViewById(R.id.deleteAction));
            if(deleteAction.getVisibility() == View.GONE){
                final Animation _anim = AnimationUtils.loadAnimation(getContext(),  R.anim.slide_in_to_right);
                deleteAction.startAnimation(_anim);
                deleteAction.setVisibility(View.VISIBLE);

            }


        }

    }

}

Every time I make a Swipe to the right, a Button is displayed to delete the item.

My problem is that when the button is displayed on a Card, scrollar, the Card is recreated, and the button is displayed in another item.

Is there any way to control this?

How can I fix that only the one who made the Swipe will be displayed?

1 answer

1


Fala Thiago,

I suffered a lot when I started working with Recyclerview.

As its name says, it reuses the cells that have already been created.

Probably, you do an if to appear the button, right?

if(swipe){
   //aparece o botão
}

Whenever you work with IF in Recyclerview, you MUST think about ELSE, then:

if(swipe){
    //aparece o botão
}else{
    //desaparece o botão
}

This will solve your problem.

Hugs.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.