美文网首页
高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)

高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)

作者: 吾乃韩小呆 | 来源:发表于2019-01-14 20:30 被阅读87次

    尊敬的各位兄弟姐妹们,韩小呆同学终于逮到时间(忙里偷闲,花样嘬死更确切),为大家带来这个效果实现方式。额,日后我争取一周给大家带来一个好玩的效果,或者是实用的效果或者...总之是开发中实用的东西。

    下面步入正题,我们先看一下支付宝和微信的效果吧:


    微信效果 支付宝效果
    韩小呆同学实现的效果

    目测,没差多少,额,不要在意细节。韩小呆是程序员界的穷x。下面开始撸码:

    1、搭建界面

    <?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:id="@+id/rl_main"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="#005B9E"
       android:focusable="true"
       android:focusableInTouchMode="true"
       tools:context=".MainActivity">
    
       <TextView
           android:id="@+id/tv_name"
           android:layout_width="wrap_content"
           android:layout_height="50dp"
           android:layout_alignParentStart="true"
           android:layout_marginStart="20dp"
           android:layout_marginTop="20dp"
           android:gravity="center"
           android:text="用户名:"
           android:textColor="#ffffff"
           android:textSize="18sp" />
    
       <EditText
           android:id="@+id/et_name"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           android:layout_marginTop="20dp"
           android:layout_marginEnd="10dp"
           android:layout_toEndOf="@+id/tv_name"
           android:paddingStart="10dp"
           android:paddingEnd="1dp"
           android:singleLine="true"
           android:textColor="#fff"
           android:textSize="14sp"
           tools:text="韩小呆" />
    
       <TextView
           android:id="@+id/tv_bank"
           android:layout_width="wrap_content"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_name"
           android:layout_alignParentStart="true"
           android:layout_marginStart="20dp"
           android:layout_marginTop="10dp"
           android:gravity="center"
           android:text="银行名:"
           android:textColor="#fff"
           android:textSize="18sp" />
    
       <EditText
           android:id="@+id/et_bank"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_name"
           android:layout_marginTop="10dp"
           android:layout_marginEnd="10dp"
           android:layout_toEndOf="@+id/tv_bank"
           android:paddingStart="10dp"
           android:paddingEnd="1dp"
           android:singleLine="true"
           android:textColor="#fff"
           android:textSize="14sp"
           tools:text="招商银行" />
    
       <TextView
           android:id="@+id/tv_bank_num"
           android:layout_width="wrap_content"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_bank"
           android:layout_alignParentStart="true"
           android:layout_marginStart="20dp"
           android:layout_marginTop="10dp"
           android:gravity="center"
           android:text="账户号:"
           android:textColor="#fff"
           android:textSize="18sp" />
    
       <EditText
           android:id="@+id/et_bank_num"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_bank"
           android:layout_marginTop="10dp"
           android:layout_marginEnd="10dp"
           android:layout_toEndOf="@+id/tv_bank_num"
           android:inputType="number"
           android:paddingStart="10dp"
           android:paddingEnd="1dp"
           android:singleLine="true"
           android:textColor="#fff"
           android:textSize="14sp"
           tools:text="6227000132080872008" />
    
       <TextView
           android:id="@+id/tv_phone"
           android:layout_width="wrap_content"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_bank_num"
           android:layout_alignParentStart="true"
           android:layout_marginStart="20dp"
           android:layout_marginTop="10dp"
           android:gravity="center"
           android:text="手机号:"
           android:textColor="#fff"
           android:textSize="18sp" />
    
       <EditText
           android:id="@+id/et_phone"
           android:layout_width="match_parent"
           android:layout_height="50dp"
           android:layout_below="@+id/tv_bank_num"
           android:layout_marginTop="10dp"
           android:layout_marginEnd="10dp"
           android:layout_toEndOf="@+id/tv_name"
           android:inputType="number"
           android:paddingStart="10dp"
           android:paddingEnd="1dp"
           android:singleLine="true"
           android:textColor="#fff"
           android:textSize="14sp"
           tools:text="15210990809" />
    
       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_below="@+id/tv_phone"
           android:layout_marginTop="20dp"
           android:orientation="horizontal"
           android:padding="20dp">
    
           <Button
               android:id="@+id/btn_add"
               android:layout_width="0dp"
               android:layout_height="wrap_content"
               android:layout_marginEnd="10dp"
               android:layout_weight="1"
               android:background="#1EA362"
               android:text="add"
               android:textAllCaps="false"
               android:textColor="#ffffff"
               android:textSize="18sp" />
    
           <Button
               android:id="@+id/btn_show"
               android:layout_width="0dp"
               android:layout_height="wrap_content"
               android:layout_marginStart="10dp"
               android:layout_weight="1"
               android:background="#1EA362"
               android:text="show"
               android:textAllCaps="false"
               android:textColor="#ffffff"
               android:textSize="18sp" />
       </LinearLayout>
    
    </RelativeLayout>
    

    Activity 的界面搭建很简单,就是 一个添加银行卡的过程,和展示 popupWindow 的相关按钮;搭建完成是这个样子的:


    Activity 界面

    popupWindow 的界面更加简单一个 RecycleView 就行了,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fl_pop"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#50000000">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="300dp"
            android:background="#07182A"
            android:orientation="vertical">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="20dp"
                    android:layout_marginTop="10dp"
                    android:text="选择到账银行卡"
                    android:textColor="#00FFF6"
                    android:textSize="16sp" />
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="20dp"
                    android:layout_marginTop="10dp"
                    android:text="平台7个工作日内线下打款,请注意到账时间"
                    android:textColor="#00CCFF"
                    android:textSize="12sp" />
    
                <View
                    android:layout_width="match_parent"
                    android:layout_height="0.5dp"
                    android:layout_alignParentBottom="true"
                    android:layout_marginTop="10dp"
                    android:background="#0C889B" />
            </LinearLayout>
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/rlv_pop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="#07182A" />
    
        </LinearLayout>
    </FrameLayout>
    
    弹出框效果

    item 的效果就不放了,太简单了,浪费篇幅。

    2、适配器逻辑

    package com.hxd.bankcardpop;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.support.annotation.NonNull;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageButton;
    import android.widget.RadioButton;
    import android.widget.TextView;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * Content:
     * Actor:韩小呆 ヾ(✿゚▽゚)ノ
     * Time:  2019/01/05 22:09
     * Update:
     * Time:
     */
    public class PopAdapter extends RecyclerView.Adapter<PopAdapter.MyViewHolder> {
    
        private Context mContext;
        private List<CardBean> cards;
        private OnItemClickListener mOnItemClickListener;
    
        private HashMap<Integer, Boolean> map;
    
    
        @SuppressLint("UseSparseArrays")
        PopAdapter(Context mContext) {
            this.mContext = mContext;
            map = new HashMap<>();
            cards = new ArrayList<>();
        }
    
    
        public void setData(List<CardBean> cardBeans) {
            this.cards.clear();
            this.cards.addAll(cardBeans);
    
            map.clear();
            for (int i = 0; i < this.cards.size(); i++) {
                map.put(i, false);
            }
        }
    
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
            return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_pop, viewGroup, false));
        }
    
        @Override
        public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int i) {
            CardBean card = cards.get(i);
    
            myViewHolder.tvName.setText(card.getCard_bank());
    
            if (card.getId() == 0) {
                myViewHolder.rbSelect.setVisibility(View.INVISIBLE);
                myViewHolder.ibDel.setVisibility(View.INVISIBLE);
            } else {
                myViewHolder.rbSelect.setVisibility(View.VISIBLE);
                myViewHolder.ibDel.setVisibility(View.VISIBLE);
            }
    
            myViewHolder.rbSelect.setChecked(map.get(i));
    
            myViewHolder.ibDel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos = myViewHolder.getLayoutPosition();
                    mOnItemClickListener.onDelClick(myViewHolder.ibDel, pos);
                }
            });
    
            myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int pos = myViewHolder.getLayoutPosition();
                    mOnItemClickListener.onSelectClick(myViewHolder.itemView, pos);
    
                    myViewHolder.rbSelect.setChecked(true);
    
                    map.put(pos, map.get(pos));
                    notifyDataSetChanged();
                    singleSelect(pos);
    
    
                }
            });
    
    
        }
    
    
        //设置单选
        private void singleSelect(int pos) {
            Set<Map.Entry<Integer, Boolean>> entries = map.entrySet();
            for (Map.Entry<Integer, Boolean> entry : entries) {
                entry.setValue(false);
            }
            map.put(pos, true);
            notifyDataSetChanged();
        }
    
    
        @Override
        public int getItemCount() {
            return cards.size();
        }
    
        class MyViewHolder extends RecyclerView.ViewHolder {
    
            private TextView tvName;
            private ImageButton ibDel;
            private RadioButton rbSelect;
    
            MyViewHolder(@NonNull View itemView) {
                super(itemView);
    
                tvName = itemView.findViewById(R.id.tv_card_name);
                ibDel = itemView.findViewById(R.id.ib_del);
                rbSelect = itemView.findViewById(R.id.cb_card);
    
            }
        }
    
        public interface OnItemClickListener {
            void onDelClick(View view, int pos);
    
            void onSelectClick(View view, int pos);
        }
    
        void setOnItemClickListener(OnItemClickListener onItemClickListener) {
            mOnItemClickListener = onItemClickListener;
        }
    }
    

    这里面值得一说的是 RecycleView 的单选处理,对于高手 很简单,一个 map 解决了。但是对于像楼主这样的菜鸟就得反复琢磨了。

    其实也很简单啦,在初始化Adapter 的时候,初始化一个map。当传入数据的时候,首先将 map内的数据清空,然后向内put进去,数据的位置和全部置位为false。 当选择某个item 的时候 将被选中的 item 的 RadioButton 变为已选,遍历map,将其余的item的选择状态均变为false。

    如果看源码 ,请看上部分代码的 map 相关。

    这里有一个细节需要注意一下,RecycleView 的item 内的 最好不要用 gone来隐藏看见,任意丢控件, 控件的隐藏和展示是成对出现的。

    3、Activity 相关逻辑

    package com.hxd.bankcardpop;
    
    import android.annotation.SuppressLint;
    import android.graphics.drawable.ColorDrawable;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.text.TextUtils;
    import android.view.Gravity;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.FrameLayout;
    import android.widget.PopupWindow;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener, PopAdapter.OnItemClickListener {
    
    
        private EditText etName;
        private EditText etBank;
        private EditText etBankNum;
        private EditText etPhone;
        private Button btnShow;
        private Button btnAdd;
        private RelativeLayout rlMain;
    
        private PopupWindow popCard;
        private PopAdapter adapter;
        private View view;
        private List<CardBean> cardBeans;
        private int tag = 5;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            rlMain = findViewById(R.id.rl_main);
            etName = findViewById(R.id.et_name);
            etBank = findViewById(R.id.et_bank);
            etBankNum = findViewById(R.id.et_bank_num);
            etPhone = findViewById(R.id.et_phone);
            btnShow = findViewById(R.id.btn_show);
            btnAdd = findViewById(R.id.btn_add);
    
            adapter = new PopAdapter(this);
    
            adapter.setOnItemClickListener(this);
            btnAdd.setOnClickListener(this);
            btnShow.setOnClickListener(this);
    
            cardBeans = new ArrayList<>();
    
            for (int i = 1; i < 5; i++) {
                cardBeans.add(new CardBean(i, "a" + i, "韩小呆" + i, "招商银行" + i, "622700013209087200" + i, "1383146022" + i));
            }
            cardBeans.add(new CardBean(0, "0", "0", "使用新卡提现", "0", "0"));
    
            initPopView();
        }
    
        @SuppressLint("InflateParams")
        private void initPopView() {
            view = getLayoutInflater().inflate(R.layout.pop_card, null, false);
            FrameLayout flPop = view.findViewById(R.id.fl_pop);
            RecyclerView rlvPop = view.findViewById(R.id.rlv_pop);
    
            rlvPop.setLayoutManager(new LinearLayoutManager(this));
            rlvPop.setAdapter(adapter);
            flPop.setOnClickListener(this);
        }
    
    
        @Override
        public void onClick(View v) {
    
            int id = v.getId();
    
            switch (id) {
                case R.id.btn_add:
                    addData();
                    break;
                case R.id.btn_show:
                    showPop();
                    break;
                case R.id.fl_pop:
                    popCard.dismiss();
                    break;
            }
    
        }
    
        private void addData() {
            tag++;
            String username = etName.getText().toString().trim();
            String bank = etBank.getText().toString().trim();
            String bankNum = etBankNum.getText().toString().trim();
            String phone = etPhone.getText().toString().trim();
    
            if (TextUtils.isEmpty(bank)) {
                Toast.makeText(this, "必须输入银行名称!", Toast.LENGTH_SHORT).show();
            } else {
                cardBeans.remove(cardBeans.size() - 1);
                cardBeans.add(new CardBean(tag, "" + tag, username, bank + tag, bankNum, phone));
                cardBeans.add(new CardBean(0, "0", "0", "使用新卡提现", "0", "0"));
                Toast.makeText(this, "添加成功!", Toast.LENGTH_LONG).show();
    
            }
        }
    
    
        private void showPop() {
            if (popCard == null) {
                popCard = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
            }
            popCard.setBackgroundDrawable(new ColorDrawable());
            popCard.showAtLocation(rlMain, Gravity.CENTER, 0, 0);
            adapter.setData(cardBeans);
            adapter.notifyDataSetChanged();
    
        }
    
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (popCard != null) {
                popCard.dismiss();
            }
        }
    
    
        @Override
        public void onDelClick(View view, int pos) {
            cardBeans.remove(pos);
            Toast.makeText(this, "删除第 " + (pos + 1) + " 条数据成功", Toast.LENGTH_LONG).show();
            popCard.dismiss();
        }
    
        @Override
        public void onSelectClick(View view, int pos) {
            Toast.makeText(this, "选择第 " + (pos + 1) + " 条数据成功", Toast.LENGTH_LONG).show();
    //        popCard.dismiss();
        }
    }
    

    这里有几个细节需要注意一下:
    1、PopupWindow内的view 最好只初始化一次,笔者看好多文章都是反复进行初始化,笔者不知道手机累不累性能咋样;
    2、PopupWindow 也最好只初始化一次;
    3、需要程序员自己整理服务器返还的数据,游戏时候服务器返回的json不是我们需要的哦。这是我们必备技能。

    下面来运行一下,看看效果哦:


    运行效果

    最后献上demo 地址: BankCardPop

    相关文章

      网友评论

          本文标题:高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)

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