zoukankan      html  css  js  c++  java
  • RecyclerView点击,移动到中间位置

    这篇博客介绍怎样给RecyclerView添加点击事件,点击某一条item,被点击的item能移动到中间位置。

    例如我们点击靠右边的03-28那一个item,这个item会自动滑到中间位置,效果如下:
    点击滑动到中间

    具体实现过程是怎么样的呢?(RecyclerView的使用前面的博客已介绍过,这里就不再赘述了。)

    首先,我们在RecyclerView的adapter里,自定义一个接口OnItemClickListener,onBindViewHolder()方法中,给item添加点击事件。示例代码如下:

    package com.li.recyclerviewdemo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    public class RvAdapter extends RecyclerView.Adapter<RvAdapter.ViewHolder> {
    
        private Context context;
        private List<TestBeans> datas;
        private RvAdapter.OnItemClickListener onItemClickListener;
        //用来标记点击的item位置,方便设置背景颜色
        private List<Integer> posList = new ArrayList<Integer>();
    
        public RvAdapter(Context context, List<TestBeans> datas) {
            super();
            this.context = context;
            this.datas = datas;
        }
    
        public void setOnItemClickListener(RvAdapter.OnItemClickListener listener){
            this.onItemClickListener = listener;
        }
    
        @Override
        public int getItemCount() {
            return datas == null ? 0 : datas.size();
        }
    
        @Override
        public void onBindViewHolder(final ViewHolder holder, int pos) {
            TestBeans bean = datas.get(pos);
            holder.tvDate.setText(bean.getDateMd());
            holder.tvDay.setText(bean.getDateDay());
            holder.tvPrice.setText(bean.getPrice());
    
            //设置点击事件的回调
            holder.itemView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(onItemClickListener != null){
                        int position = holder.getPosition();
                        onItemClickListener.onItemClick(holder.itemView, position);
                        //标记点击的item位置
                        posList.clear();
                        posList.add(position); 
                    }
                }
            });
    
            if(posList.contains(pos)){
                holder.itemView.setBackgroundColor(context.getResources().getColor(R.color.green));
            }else{
                holder.itemView.setBackgroundColor(context.getResources().getColor(R.color.grey));
            }
        }
    
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
            View v = LayoutInflater.from(arg0.getContext()).inflate(
                    R.layout.rv_adapter_item, arg0, false);
            ViewHolder vh = new ViewHolder(v);
            return vh;
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            TextView tvDate;
            TextView tvDay;
            TextView tvPrice;
    
            public ViewHolder(View itemView) {
                super(itemView);
                tvDate = (TextView) itemView.findViewById(R.id.tvDate);
                tvDay = (TextView) itemView.findViewById(R.id.tvDay);
                tvPrice = (TextView) itemView.findViewById(R.id.tvPrice);
            }
        }
    
        /**
         * 自定义的点击事件接口
         * @author lish
         */
        public interface OnItemClickListener{
            void onItemClick(View view, int position);
    //      void onItemLongClick(View view, int position); //长按
        }
    }
    

    MainActivity.java 中,adapter添加点击事件,然后被点击的item移动到中间位置。

    adapter.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(MainActivity.this, "-->" + position, Toast.LENGTH_SHORT).show();
                    moveToMiddle(view);
                    adapter.notifyDataSetChanged();
                }
            });

    View移动的方法:

        /**
         * 滚动到中间位置
         * @param clkView  被点击的View
         */
        public void moveToMiddle(View clkView){
            int itemWidth = clkView.getWidth();
            int screenWidth = getResources().getDisplayMetrics().widthPixels;
            int scrollWidth = clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);
            rvView.scrollBy(scrollWidth, 0);
        }

    移动到中间位置基本原理:先计算出屏幕宽度screenWidth,被点击View的宽度itemWidth,被点击View距离左边的距离为clkView.getLeft(),需要移动的宽度是 clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);

    这些距离计算,在纸上画一下就比较清晰了,我画了一下,有点难看,但是能说明问题,不清楚的多想想。
    计算距离

    完整示例代码如下:

    package com.li.recyclerviewdemo;
    
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    import java.util.Locale;
    
    import com.li.recyclerviewdemo.RvAdapter.OnItemClickListener;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
    
        private RecyclerView rvView;
        private LinearLayoutManager layoutManager;
        private RvAdapter adapter;
        private List<TestBeans> beanList = new ArrayList<TestBeans>();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            getDatas();
            initView();
        }
    
        private void initView() {
            rvView = (RecyclerView) findViewById(R.id.rvView);
            layoutManager = new LinearLayoutManager(this);
            layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
            rvView.setLayoutManager(layoutManager);
    
            adapter = new RvAdapter(this, beanList);
            rvView.setAdapter(adapter);
    
            adapter.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    Toast.makeText(MainActivity.this, "-->" + position, Toast.LENGTH_SHORT).show();
                    moveToMiddle(view);
                    adapter.notifyDataSetChanged();
                }
            });
        }
    
        /**
         * 滚动到中间位置
         * @param clkView  被点击的View
         */
        public void moveToMiddle(View clkView){
            int itemWidth = clkView.getWidth();
            int screenWidth = getResources().getDisplayMetrics().widthPixels;
            int scrollWidth = clkView.getLeft() - (screenWidth / 2 - itemWidth / 2);
            rvView.scrollBy(scrollWidth, 0);
        }
    
        private void getDatas() {
            Calendar cal = Calendar.getInstance(Locale.CHINA);
            SimpleDateFormat sdfMd = new SimpleDateFormat("MM-dd");
    
            String[] dayNames = getResources().getStringArray(R.array.week_day);
    
            for (int i = 0; i < 15; i++) {
                cal.add(Calendar.DAY_OF_MONTH, 1);
                Date date = cal.getTime();
                String dateMd = sdfMd.format(date);
    
                int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
                if (dayOfWeek < 0) {
                    dayOfWeek = 0;
                }
                String day = dayNames[dayOfWeek];
    
                TestBeans bean = new TestBeans();
                bean.setDateMd(dateMd);
                bean.setDateDay(day);
                bean.setPrice("¥" + (i+1) * 100); 
    
                beanList.add(bean);
            }
        }
    
    }
    
  • 相关阅读:
    Splunk_转发器配置_AD
    Splunk SPL 时间转换
    Splunk_索引自动清理历史数据
    Python 备查 线程池
    Splunk_SPL 排除搜索结果
    Splunk_SPL 查询时间范围
    质量的分级
    各类BOM
    Jmeter负载测试的注意事项
    MEM的面试记录
  • 原文地址:https://www.cnblogs.com/lishbo/p/9956009.html
Copyright © 2011-2022 走看看