美文网首页
RecylerView(GridView布局)实现充值界面效果

RecylerView(GridView布局)实现充值界面效果

作者: 猩程变 | 来源:发表于2017-10-06 17:17 被阅读194次

    RecylerView(GridView布局)实现充值界面效果

    项目中有一个充值的效果如下:


    效果图

    之前为了赶项目进度,也没有多想,这不是很简单的么?5个TextView加1个EditText不就搞定了么?
    的确这样做是可以实现的,而且也在规定时间内完成了项目。(但是存在局限性)
    由于项目中多次的使用了RecycleView,然后发现这个用RecycleView实现效果会更好(布局更灵活,不限制个数),完成后的效果:


    有角标
    无角标
    • 1、数据传递效果的展示
      首先分析下这个界面需要的数据,由于这个界面是后台通过两个字段判断实现的效果
       String data = "3,9,30,50,100";
       //isDiscount :1、有角标 2、无角标
        String isDiscount = "1";
    

    我们首先要通过IsDiscount这个字段来判断是否显示带角标的控件,以及data字段来判断动态添加几个控件

    • 2、界面实现效果分析
      1、组件选择
      文章开始就说到了,我们选用的是RecycleView这个控件结合GridView布局实现效果
      2、RecyeView Adapter布局分析
      ①有角标TextView
      ②正常无角标TextView
      ③EditText输入框
      布局如上三种,大家都知道RecycleView的强大,现在我们就利用它其中的ItemType这个功能,RecyleView很多复杂的界面都是通过ItemType这个属性来实现的。
      3、具体代码的实现
      ①ItemType种类的控制
     @Override
     public DemoAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         switch (viewType) {
           case ItemModel.ONE:
                    ///左上角三角标识布局;
                    return new CornorViewHoler(LayoutInflater.from(parent.getContext()).inflate(R.layout.corner_one, parent, false));
         case ItemModel.TWO:
                    return new OneViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.one, parent, false));
          case ItemModel.THREE:
                    return new TWoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.two, parent, false));
            }
            return null;
        }
    

    在onCreateViewHolde这个方法中添加所需要的三种布局文件
    ②Item数据封装
    在这个Adapter中,由于我需要知道几个条件,第一个是当前选中的状态是否是免费的标志,第二个是当前选中的值,所以封装了一个ItemModel的类用于处理数据

    public class ItemModel implements Serializable {
        //左上角三角图标
        public static final int ONE = 1001;
        //textview布局
        public static final int TWO = 1002;
        //edittext布局
        public static final int THREE = 1003;
        public int type;
        public Object data;
        //是否免费的标志
        public boolean isFree;
        public ItemModel(int type, Object data, boolean isFree) {
            this.type = type;
            this.data = data;
        }
    }
    

    好了前期的准备工作差不多了,现在我们就该对Adapter中的逻辑进行处理了。先上Adapter的完整代码

    public class DemoAdapter extends RecyclerView.Adapter<DemoAdapter.BaseViewHolder> {
        private ArrayList<ItemModel> dataList = new ArrayList<>();
        private int lastPressIndex = -1;
        private Context mContext;
    
        public void replaceAll(ArrayList<ItemModel> list, Context context) {
            mContext = context;
            dataList.clear();
            if (list != null && list.size() > 0) {
                dataList.addAll(list);
            }
            notifyDataSetChanged();
        }
    
        @Override
        public DemoAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            switch (viewType) {
    
                case ItemModel.ONE:
                    ///左上角三角标识布局;
                    return new CornorViewHoler(LayoutInflater.from(parent.getContext()).inflate(R.layout.corner_one, parent, false));
                case ItemModel.TWO:
                    return new OneViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.one, parent, false));
    
                case ItemModel.THREE:
                    return new TWoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.two, parent, false));
            }
            return null;
        }
    
        @Override
        public void onBindViewHolder(DemoAdapter.BaseViewHolder holder, int position) {
    
            holder.setData(dataList.get(position).data);
        }
    
        @Override
        public int getItemViewType(int position) {
            return dataList.get(position).type;
        }
    
        @Override
        public int getItemCount() {
            return dataList != null ? dataList.size() : 0;
        }
    
        public class BaseViewHolder extends RecyclerView.ViewHolder {
    
            public BaseViewHolder(View itemView) {
                super(itemView);
            }
    
            void setData(Object data) {
            }
        }
    
        private class OneViewHolder extends BaseViewHolder {
            private TextView tv;
    
            public OneViewHolder(View view) {
                super(view);
                tv = (TextView) view.findViewById(R.id.tv);
    
                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e("TAG", "OneViewHolder: ");
                        notyfy = 0;
                        int position = getAdapterPosition();
                        ItemModel model = dataList.get(position);
                        Log.e("TAG", "OneViewHolder: " + model.toString());
                        EventBus.getDefault().post(model);
                        if (lastPressIndex == position) {
                            lastPressIndex = -1;
                        } else {
                            lastPressIndex = position;
                        }
                        notifyDataSetChanged();
    
    
                    }
    
                });
            }
    
            @Override
            void setData(Object data) {
                if (data != null) {
                    String text = (String) data;
                    tv.setText(text);
                    if (getAdapterPosition() == lastPressIndex) {
                        tv.setSelected(true);
                        tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.white));
    
                    } else {
                        tv.setSelected(false);
                        tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.blue_500));
                    }
    
                }
    
    
            }
        }
    
        int notyfy = 0;
    
        private class TWoViewHolder extends BaseViewHolder {
            private EditText et;
            private String chargeFunds;
    
            public TWoViewHolder(View view) {
                super(view);
    
                et = (EditText) view.findViewById(R.id.et);
                final int position = getAdapterPosition();
                //ItemModel model = dataList.get(position);
                //Log.e("TWoViewHolder", "TWoViewHolder: "+model.toString());
                Log.e("TWoViewHolder", "TWoViewHolder: ");
              et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                    @Override
                    public void onFocusChange(View v, boolean hasFocus) {
                        if (hasFocus) {
    
                            if (lastPressIndex != position) {
                                notifyItemChanged(lastPressIndex);
                                lastPressIndex = position;
                            }
                        }
                    }
                });
                et.addTextChangedListener(new TextWatcher() {
    
    
                    @Override
                    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
                    }
    
                    @Override
                    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                        if (charSequence != null || !charSequence.equals("")) {
                            try {
                                int str = Integer.parseInt(String.valueOf(charSequence));
    
                                if (str < 9) {
    
                                    Toast.makeText(mContext, "输入的金额小于最小支付金额9元", Toast.LENGTH_SHORT).show();
                                    et.setSelection(et.getText().length());
                                }
                                if (str > 2000) {
                                    Toast.makeText(mContext, "输入的金额大于最大支付金额2000元", Toast.LENGTH_SHORT).show();
                                    et.setText("2000");
                                    et.setSelection(et.getText().length());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
    
                        }
                    }
    
                    @Override
                    public void afterTextChanged(Editable editable) {
    
    
                        if (editable.length() > 0) {
                            String inputText = et.getText().toString().trim();
                            if (Double.parseDouble(inputText) < 9) {
                                chargeFunds = "9";
                            } else if (Double.parseDouble(inputText) > 2000) {
                                chargeFunds = "2000";
                            } else {
                                chargeFunds = inputText;
                            }
                        }
    
                        String funds = chargeFunds + "元";
                        ItemModel model = new ItemModel(ItemModel.THREE, funds, false);
                        EventBus.getDefault().post(model);
                    }
                });
    
    
            }
    
    
            @Override
            void setData(Object data) {
                super.setData(data);
                final int position = getAdapterPosition();
                if (position == lastPressIndex)
                    et.requestFocus();
                else
                    et.clearFocus();
            }
        }
    
        private class CornorViewHoler extends BaseViewHolder {
            private TextView tv;
    
            public CornorViewHoler(View view) {
                super(view);
                tv = (TextView) view.findViewById(R.id.tv);
                //int position = getAdapterPosition();
                //ItemModel model = dataList.get(position);
                //Log.e("TAG", "OneViewHolder: "+model.toString());
                itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Log.e("TAG", "OneViewHolder: ");
                        notyfy = 0;
                        int position = getAdapterPosition();
                        ItemModel model = dataList.get(position);
                        EventBus.getDefault().post(model);
                        if (lastPressIndex == position) {
                            lastPressIndex = -1;
                        } else {
                            lastPressIndex = position;
                        }
                        notifyDataSetChanged();
    
    
                    }
    
                });
            }
    
            @Override
            void setData(Object data) {
                if (data != null) {
                    String text = (String) data;
                    tv.setText(text);
                    if (getAdapterPosition() == lastPressIndex) {
                        tv.setSelected(true);
                        tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.white));
    
                    } else {
                        tv.setSelected(false);
                        tv.setTextColor(ContextCompat.getColor(itemView.getContext(), R.color.blue_500));
                    }
    
                }
            }
        }
    }
    

    上述代码中数据传递使用的是EventBus3.0,所以需要在gradle文件添加如下引用:

    compile 'org.greenrobot:eventbus:3.0.0'
    

    现在开始对Adapter类进行分析,在Adapter类中我们创建了3个ViewHolder(CornorViewHoler、TWoViewHolder、OneViewHolder)在这三个ViewHolder中实现各自的逻辑,同时三个类中同时继承了void setData(Object data) 接口处理是否为选中状态、是否需要更改背景颜色以及状态
    其他部分的代码都比较简单,不过在处理TWoViewHolder这个类的时候有点小麻烦(EditText),首先大家看到EditText有一个取值范围的(9~2000),这个通过addTextChangedListener监听来实现即可

        et.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    }
                    @Override
                    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                        if (charSequence != null || !charSequence.equals("")) {
                            try {
                                int str = Integer.parseInt(String.valueOf(charSequence));
                                if (str < 9) {
                                    Toast.makeText(mContext, "输入的金额小于最小支付金额9元", Toast.LENGTH_SHORT).show();
                                    et.setSelection(et.getText().length());
                                }
                                if (str > 2000) {
                                    Toast.makeText(mContext, "输入的金额大于最大支付金额2000元", Toast.LENGTH_SHORT).show();
                                    et.setText("2000");
                                    et.setSelection(et.getText().length());
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    @Override
                    public void afterTextChanged(Editable editable) {
    
    
                        if (editable.length() > 0) {
                            String inputText = et.getText().toString().trim();
                            if (Double.parseDouble(inputText) < 9) {
                                chargeFunds = "9";
                            } else if (Double.parseDouble(inputText) > 2000) {
                                chargeFunds = "2000";
                            } else {
                                chargeFunds = inputText;
                            }
                        }
    
                        String funds = chargeFunds + "元";
                        ItemModel model = new ItemModel(ItemModel.THREE, funds, false);
                        EventBus.getDefault().post(model);
                    }
                });
    

    到这里差不多写完了,是不是就大功告成了?别急,还有一个问题,点击EditText的时候,TextView的状态还没有消失呢,怎么办?

    当页面刷新的时候 如果当前选中的是这个输入框就让它获取到并得到焦点,所以我们在TWoViewHolder类中的setData() 方法中让它获取焦点,将最后的位置传递给它

      @Override
            void setData(Object data) {
                super.setData(data);
                final int position = getAdapterPosition();
                if (position == lastPressIndex)
                    et.requestFocus();
                else
                    et.clearFocus();
            }
    

    这样就差不多了,然后我们对EdiText的焦点进行监听(setOnFocusChangeListener),Notifycation布局文件即可

      et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                    @Override
                    public void onFocusChange(View v, boolean hasFocus) {
                        if (hasFocus) {
    
                            if (lastPressIndex != position) {
                                notifyItemChanged(lastPressIndex);
                                lastPressIndex = position;
                            }
                        } 
                    }
                });
    

    代码讲到这里就可以实现上面的效果了,下面将其他布局文件代码贴出来
    MainActivity.class

    public class MainActivity extends AppCompatActivity {
    
        private RecyclerView recyclerView;
        private DemoAdapter adapter;
        private TextView tvPay;
        private TextView tv_recharge_money;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            tv_recharge_money = (TextView) findViewById(R.id.tv_recharge_money);
            recyclerView = (RecyclerView) findViewById(R.id.recylerview);
            tvPay = (TextView) findViewById(R.id.tvPay);
            //setHasFixedSize 的作用就是确保尺寸是通过用户输入从而确保RecyclerView的尺寸是一个常数。
            // RecyclerView 的Item宽或者高不会变(提升性能)。
            recyclerView.setHasFixedSize(true);
            //recycleview设置布局方式,GridView (一行三列)
            recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
            recyclerView.setAdapter(adapter = new DemoAdapter());
            adapter.replaceAll(getData(),this);
            EventBus.getDefault().register(this);
    
        }
    
        public ArrayList<ItemModel> getData() {
            String data = "3,9,30,50,100";
            // isDiscount :1、有角标 2、无角标
            String isDiscount = "2";
            String dataArr[] = data.split(",");
            ArrayList<ItemModel> list = new ArrayList<>();
            for (int i = 0; i < dataArr.length; i++) {
                String count = dataArr[i] + "元";
                if (isDiscount.equals("1") && i == 0) {
                    list.add(new ItemModel(ItemModel.ONE, count, true));
                } else {
                    list.add(new ItemModel(ItemModel.TWO, count, false));
                }
            }
            list.add(new ItemModel(ItemModel.THREE, null, false));
    
            return list;
        }
    
        @Subscribe(threadMode = ThreadMode.MAIN)
        public void getAdapterClickInfo(ItemModel model) {
            String money = model.data.toString().replace("元", "");
            tv_recharge_money.setText(money);
            if (model.isFree==true){
                Toast.makeText(this,"点击的是带免费标签的",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(this,"点击的是正常标签的",Toast.LENGTH_SHORT).show();
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            EventBus.getDefault().unregister(this);
        }
    }
    
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.wangchang.testrecharge.MainActivity">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="12dp"
                android:background="@color/grey_300" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:background="@color/white"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:padding="8dp">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="充值账号:"
                    android:textColor="@color/black" />
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="15013678968"
                    android:textColor="@color/yellow_900" />
            </LinearLayout>
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/grey_300" />
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:background="@color/white"
                android:gravity="center_vertical"
                android:orientation="horizontal"
                android:padding="8dp">
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="充值金额:"
                    android:textColor="@color/black" />
    
                <TextView
                    android:id="@+id/tv_recharge_money"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="100"
                    android:textColor="@color/yellow_900" />
            </LinearLayout>
    
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="@color/grey_300" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="8dp"
                android:text="选择充值金币:" />
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recylerview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:padding="12dp" />
    
        </LinearLayout>
    
        <TextView
            android:id="@+id/tvPay"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_alignParentBottom="true"
            android:layout_margin="24dp"
            android:background="@drawable/tv_bg_pay"
            android:gravity="center"
            android:text="立即充值"
            android:textColor="@color/white" />
    </RelativeLayout>
    

    corner_one.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="42dp"
            android:gravity="center"
            android:layout_margin="8dp"
            android:padding="12dp"
            android:background="@drawable/tv_bg"
            android:textColor="@color/blue_500" />
    
        <ImageView
            android:layout_margin="8dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:srcCompat="@drawable/free_click"
            android:id="@+id/imageView" />
    </FrameLayout>
    

    one.xml

    <?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="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="42dp"
            android:gravity="center"
            android:layout_margin="8dp"
            android:padding="12dp"
            android:background="@drawable/tv_bg"
            android:textColor="@color/blue_500" />
    </LinearLayout>
    

    two.xml

    <?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="wrap_content"
        android:orientation="vertical">
    
        <EditText
            android:id="@+id/et"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="8dp"
            android:background="@drawable/bg_et"
            android:gravity="center"
            android:hint="9-2000元"
            android:inputType="number"
            android:padding="12dp"
            android:textSize="12sp" />
    </LinearLayout>
    

    好了,代码到此为止,效果也差不多了,有兴趣的朋友可以自行尝试下,欢迎大家一起交流,如有更好的建议或者意见可致电lcf_spark@163.com

    相关文章

      网友评论

          本文标题:RecylerView(GridView布局)实现充值界面效果

          本文链接:https://www.haomeiwen.com/subject/bvrryxtx.html