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

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

下面步入正题,我们先看一下支付宝和微信的效果吧:
高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第1张图片

高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第2张图片
高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第3张图片
目测,没差多少,额,不要在意细节。韩小呆是程序员界的穷x。下面开始撸码:

1、搭建界面




   

   

   

   

   

   

   

   

   

       

Activity 的界面搭建很简单,就是 一个添加银行卡的过程,和展示 popupWindow 的相关按钮;搭建完成是这个样子的:
高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第4张图片

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




    

        

            

            

            
        

        

    

高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第5张图片

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 {

    private Context mContext;
    private List cards;
    private OnItemClickListener mOnItemClickListener;

    private HashMap map;


    @SuppressLint("UseSparseArrays")
    PopAdapter(Context mContext) {
        this.mContext = mContext;
        map = new HashMap<>();
        cards = new ArrayList<>();
    }


    public void setData(List 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> entries = map.entrySet();
        for (Map.Entry 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 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不是我们需要的哦。这是我们必备技能。

下面来运行一下,看看效果哦:
高仿 微信、支付宝 选择银行卡效果(PopupWindow实现)_第6张图片

最后献上demo 地址: BankCardPop

欢迎关注

你可能感兴趣的:(Android,ui相关)