Simple implementation of RecyclerView sideslip deletion menu, simple and clear, strong portability

Keywords: Android xml encoding Eclipse

I. Preface

There are many on-line implementation of this demand, but too many fancy functions are not used, and their own project needs are not suitable for use, but it is too difficult to change the source code, they wrote a.

Two. Steps

Rewrite either recyclerview or item. I choose to rewrite item here.

2.1 Implementing item layout

As shown in the figure below, you need to make the layout of item as follows.

      

The layout file is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <!--Dividing line  -->
    <View 
        android:layout_width="match_parent"
        android:layout_height="10dp"
        />
    
    <com.maxence.tvfocusdemo.ItemView 
        android:id="@+id/itemview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
           android:scrollbars="none"
        >
        <LinearLayout 
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:orientation="horizontal"
            >
            <TextView 
                android:id="@+id/tv1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="I am item"
                android:textColor="@android:color/white"
		android:background="#0000ff"
                android:gravity="center"
                />
               <TextView 
                android:id="@+id/tv2"
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:text="delete"
                android:textColor="@android:color/white"
		android:background="#ff0000"
                android:gravity="center"
                />
        </LinearLayout>
    </com.maxence.tvfocusdemo.ItemView>
  
</LinearLayout>

I'm here to rewrite Horizontal ScrollView.

public class ItemView extends HorizontalScrollView {

2.1.1 Gets the width of the screen, then prepares to dynamically set the view on the left of item to fill the screen, and then the deleted view on the right is squeezed out of the screen:

public ItemView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		init();
	}
	private void init() {
		WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
		Display display = wm.getDefaultDisplay();
		DisplayMetrics metrics = new DisplayMetrics();
		display.getMetrics(metrics);
		int pixels = metrics.widthPixels;
		mScreenWidth = pixels;
		
	}

2.1.2 Fill the full screen on the left side of onmeasure dynamic setting item:

        @Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		
		if (!islayout) {  //Here's a judgment because onMeasure onlayout executes many times
			vg = (LinearLayout) getChildAt(0);
			//view on the left
			view = (TextView) vg.getChildAt(0);
			//view on the right, not here for the time being
		//	View view1 = vg.getChildAt(1);	
			//Set the view width on the left to fill the barbarian screen
			android.widget.LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mScreenWidth, LinearLayout.LayoutParams.MATCH_PARENT);
			view.setLayoutParams(params);
			islayout = true;		
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

2.1.3 Gets the width of the deleted item on the right, which is convenient for judging the sliding distance and automatically opening or closing the item in the back sliding.

        @Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		
		if (!islayout) {  //Here's a judgment because onMeasure onlayout executes many times
			
			vg = (LinearLayout) getChildAt(0);  //Horizontal ScrollView can only have one child control. In the layout file, I use Linear Layout
			//view on the left
			view = (TextView) vg.getChildAt(0);
			//view on the right, not here for the time being
		//	View view1 = vg.getChildAt(1);	
			//Set the view width on the left to fill the barbarian screen
			android.widget.LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mScreenWidth, LinearLayout.LayoutParams.MATCH_PARENT);
			view.setLayoutParams(params);
			islayout = true;		
		}
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}

2.2 It can automatically hide and open in the process of left-slip and right-slip.

To monitor onTouchEvent, we only need to monitor up and cancel states:

        @Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
		//Used to record current
		case MotionEvent.ACTION_DOWN:
			if(mylistener!=null){
				mylistener.onlick(this);
			}	
			return true;		
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			int scrollX = getScrollX();
			if(scrollX>=viewWidth/2){
				openMenu();
			}else{
				closeMenu();
			}
			//The smoothScrollTo method does not work if the direct break
			return true;
		default:
			break;
		}
		return super.onTouchEvent(ev);
	}
  

Here's the difference between scrollto and scrollBy:

scrollTo: slides to the specified coordinates, invalid settings many times

scrollBy: Addition or subtraction of sliding coordinate values, the origin of which is the last sliding coordinate.

	/**
	 * Display full right view
	 */
	public void openMenu(){
		smoothScrollTo(viewWidth,0);
		mylistener.open(this);
		//adapter.setOpenView(this);
	}
	/**
	 * Close the right view
	 */
	public void closeMenu(){
		smoothScrollTo(0, 0);
	}

2.3 When clicking on other items, close the item that is being opened

We have a callback function implementation here:

	interface Mylistener{
		void onlick(ItemView v);
		void open(ItemView v);
	}

Then, in action_down, decide if you need to close:

                //Used to record current
		case MotionEvent.ACTION_DOWN:
			if(mylistener!=null){
				mylistener.onlick(this);
			}
			return true;	

Externally, that is, the adpater page provides a listening method:

public  void setOnMyListener(Mylistener l){
		mylistener=l;
	}

apadter implementation:

	holder.itView.setOnMyListener(new Mylistener() {	
			@Override
			public void onlick(ItemView v) {
				if(mItemView!=null&&mItemView!=v){
					mItemView.closeMenu();
				}
			}
			@Override
			public void open(ItemView v) {
				mItemView=v;
			}
			
		});

2.4 Implement click delete item:

Monitoring in adapter

holder.tv_r.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				holder.itView.closeMenu();
				String string = aList.get(position);
				aList.remove(position);
				aList.add(0,string);
				notifyDataSetChanged();
			}
		});

In this way, we will basically accomplish:

Attach the complete adapter code:

public class MyAdapter  extends RecyclerView.Adapter<Holder> {

	private  Context mContext;
	private ArrayList<String> aList;
	private ItemView mItemView;
	private  MyAdapter adapter;
	public MyAdapter(Context context) {
		mContext=context;
		aList=new ArrayList<String>();
		for(int x=0;x<20;x++){
			aList.add(x+"");
		}
	}
	
	@Override
	public int getItemCount() {
		return aList.size();
	}	
	@Override
	public void onBindViewHolder(final Holder holder, final int position) {
		
		holder.tv_l.setText("This is the entry:"+aList.get(position));	
		
		holder.tv_r.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				holder.itView.closeMenu();
				String string = aList.get(position);
				aList.remove(position);
				aList.add(0,string);
				notifyDataSetChanged();
			}
		});	
		holder.itView.setOnMyListener(new Mylistener() {
			
			@Override
			public void onlick(ItemView v) {
				if(mItemView!=null&&mItemView!=v){
					mItemView.closeMenu();
				}
			}
			@Override
			public void open(ItemView v) {
				mItemView=v;
			}
			
		});
	}
	@Override
	public Holder onCreateViewHolder(ViewGroup parent, int arg1) {
		LayoutInflater inflater = LayoutInflater.from(mContext);
		View view = inflater.inflate(R.layout.activity_main1,parent,false);	
		return new Holder(view);	
	}	
	class Holder extends RecyclerView.ViewHolder{
		TextView tv_l;
		TextView tv_r;
		ItemView itView;
		public Holder(View itemView) {
			super(itemView);
			tv_l = (TextView) itemView.findViewById(R.id.tv1);
			tv_r = (TextView) itemView.findViewById(R.id.tv2);
			itView=(ItemView) itemView.findViewById(R.id.itemview);
		}
		
	}
}

Simple calls in action are enough:

recyclerView = (RecyclerView) findViewById(R.id.rl_view);	
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter adapter =new MyAdapter(this);
recyclerView.setAdapter(adapter);
Code portal eclipse version

  


Posted by zplits on Sat, 18 May 2019 18:47:20 -0700