IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android订单更多操作popwindow -> 正文阅读

[移动开发]Android订单更多操作popwindow

转发备注:https://blog.csdn.net/ctianju/article/details/122109664

背景

淘宝,京东等购物类App订单列表都有“更多”着操作,比如删除订单,查看物流等操作;

分析

Android自带的PopWindow组件就能很好的满足,但是还有问题需要分析解决:
1、弹框的方向问题,如果列表滑动到底部需要向上弹,顶部就向下弹;
解决:计算点击“更多”文字的位置,来动态的改变弹出的方向
2、弹框的背景样式;
解决:最简单利用点9图片作为背景
3、订单列表的 item 数据返回问题
解决:和后端沟通,更多操作的按钮就放到一个list,普通的就放到一个list
4、列表按钮太多放不下问题
解决:利用横向滚动的HorizontalScrollView 动态添加按钮进去

显上效果图

在这里插入图片描述

先组建PopWindow

1、重写PopupWindow

public class ActionMorePopWindow extends PopupWindow {
    private Context context;
    private View conentView;
    private RecyclerView listView;
    private ActionSelectPopularAdapter selectAdapter;
    List<OrderActionBtnEntity> typeSelectlist = new ArrayList();
    int[] location = new int[2];
    private OnPopWindowItemListener onItemListener;
    private LinearLayout llParent;
    public interface OnPopWindowItemListener {
         void OnItemListener(int position, OrderActionBtnEntity orderActionEntity);
    }

    public void setOnItemMyListener(OnPopWindowItemListener onItemListener) {
        this.onItemListener = onItemListener;
    }

    public ActionMorePopWindow(Context context) {
        this.context = context;
        initView();
    }

    public ActionMorePopWindow(Context context, List<OrderActionBtnEntity> typeSelectlist) {
        this.context = context;
        this.typeSelectlist = typeSelectlist;
        initView();
    }

    private void initView() {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.conentView = inflater.inflate(R.layout.popwindow, null);
        // 设置PopupWindow的View
        this.setContentView(conentView);
        // 设置PopupWindow弹出窗体的宽
        this.setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
        // 设置PopupWindow弹出窗体的高
        this.setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
        // 设置PopupWindow弹出窗体可点击
        this.setFocusable(true);
        this.setOutsideTouchable(true);
        // 刷新状态
        this.update();
        // 实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0000000000);
        // 点back键和其他地方使其消失,设置了这个才能触发OnDismisslistener ,设置其他控件变化等操作
        this.setBackgroundDrawable(dw);
        this.listView = conentView.findViewById(R.id.lv_list);
        //设置适配器
        this.selectAdapter = new ActionSelectPopularAdapter(typeSelectlist, context);
        this.listView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
        llParent = conentView.findViewById(R.id.llParent);
        SpacingDecoration itemDecoration = new SpacingDecoration(context, 1);
        this.listView.addItemDecoration(itemDecoration);
        this.listView.setAdapter(selectAdapter);
        this.selectAdapter.setOnItemClickerListener(new ActionSelectPopularAdapter.OnItemClickerListener() {
            @Override
            public void onItemClick(int position) {
                if (isShowing()) {
                    dismiss();
                }
                onItemListener.OnItemListener(position, typeSelectlist.get(position));
            }
        });

        this.setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss() {
            }
        });
    }

    //设置数据
    public void setDataSource(List<OrderActionBtnEntity> typeSelectlist) {
        this.typeSelectlist = typeSelectlist;
        this.selectAdapter.notifyDataSetChanged();
    }

    public void showPopupWindow(View v) {
        v.getLocationOnScreen(location); //获取控件的位置坐标
        //获取自身的长宽高
        conentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        if (location[1] > DensityUtil.INSTANCE.getScreenHeight(v.getContext()) / 2 + 100) {
            //若是控件的y轴位置大于屏幕高度的一半,向上弹出,
            llParent.setBackground(v.getContext().getDrawable(R.drawable.order_doctor_more_up_bg));
            //显示指定控件的上方
            // 偏移距离根据UI的慢慢调整
            this.showAtLocation(v, Gravity.NO_GRAVITY, location[0] - DensityUtil.INSTANCE.dp2px(10), location[1] - listView.getMeasuredHeight()-DensityUtil.INSTANCE.dp2px(17));
        } else {
            llParent.setBackground(v.getContext().getDrawable(R.drawable.order_doctor_more_down_bg));
            //显示指定控件的下方
            // 偏移距离根据UI的慢慢调整
            this.showAsDropDown(v, 0- DensityUtil.INSTANCE.dp2px(10), 0);
        }
    }

}

2、绘制popwindow布局
popwindow.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:id="@+id/llParent"
    xmlns:tools="http://schemas.android.com/tools">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/lv_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#f5f5f5"
        tools:itemCount="2"
        tools:listitem="@layout/pop_item_action"
        android:scrollbars="none"
      />

</LinearLayout>

3、绘制popwindow 里面RecyclerView的item布局
pop_item_action.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:gravity="center_horizontal"
    android:background="@color/white"
    android:orientation="vertical"
    android:padding="7dp">

    <TextView
        android:layout_gravity="left"
        android:id="@+id/orderActionTitle"
        android:layout_width="wrap_content"
        tools:text="删除订单"
        android:layout_height="wrap_content"
        android:textColor="#ff666666"
        android:textSize="12sp" />
</LinearLayout>

4、ActionSelectPopularAdapter

public class ActionSelectPopularAdapter extends RecyclerView.Adapter<ActionSelectPopularAdapter.MoreActionHolder> {
    private List<OrderActionBtnEntity> mData = new ArrayList<>();
    private Context context;
   private OnItemClickerListener onItemClickerListener;
    public ActionSelectPopularAdapter(List<OrderActionBtnEntity> mData, Context context) {
        this.mData.clear();
        this.mData.addAll(mData);
        this.context = context;
    }

    public void setOnItemClickerListener(OnItemClickerListener onItemClickerListener) {
        this.onItemClickerListener = onItemClickerListener;
    }

    @Override
    public MoreActionHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View itemRoot = LayoutInflater.from(parent.getContext()).inflate(R.layout.pop_item_action, parent, false);
        return new MoreActionHolder(itemRoot);
    }

    @Override
    public void onBindViewHolder(MoreActionHolder holder, int position) {
        OrderActionBtnEntity item = this.mData.get(position);
        holder.bind(item);
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    class MoreActionHolder extends RecyclerView.ViewHolder {
        private final TextView orderActionTitle;
        public MoreActionHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            orderActionTitle = itemView.findViewById(R.id.orderActionTitle);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onItemClickerListener.onItemClick(getAdapterPosition());
                }
            });
        }
        public void bind(OrderActionBtnEntity item) {
            orderActionTitle.setText(item.getName());
        }
    }
    public interface OnItemClickerListener{
        void onItemClick(int position);
    }
}

5、OrderActionBtnEntity

// 订单的操作按钮
class OrderActionBtnEntity {
    var color: String? = null
    var type: Int = -1 //
    var name: String? = null //

    constructor(type: Int, name: String?,color: String? ) {
        this.type = type
        this.name = name
        this.color = color
    }
}

6、两个弹框背景的点9图片
1、order_doctor_more_up_bg
在这里插入图片描述
2、order_doctor_more_down_bg
在这里插入图片描述

组件外部的RecyclerView

1、activity_main.xm

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="#F5F5F5"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/mainRvList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</LinearLayout>

2、MainActivity 包括构造数据源

class MainActivity : AppCompatActivity() {
    private val normalButtonsList = mutableListOf<OrderActionBtnEntity>()
    private val normalButtonsList2 = mutableListOf<OrderActionBtnEntity>()
    private val normalButtonsList3 = mutableListOf<OrderActionBtnEntity>()

    private val moreButtonsList = mutableListOf<OrderActionBtnEntity>()
    private val moreButtonsList2 = mutableListOf<OrderActionBtnEntity>()
    private val moreButtonsList3 = mutableListOf<OrderActionBtnEntity>()

    private val dataList = mutableListOf<OrderEntity>()

    companion object {
        const val DELETE_TYPE = 1 // 删除按钮类型
        const val GO_SHOPPING_CART_TYPE = 2 // 再次购买按钮
        const val MAKE_AN_INVOICE_TYPE = 3   // 去咨询
        const val MAKE_AN_SHARE_MORE_TYPE = 4  // 去咨询
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initData()

        val adapter = MainRvAdapter(dataList, this)

        mainRvList.layoutManager = LinearLayoutManager(this)
        val spacingDecoration = SpacingDecoration(this, 10)
        spacingDecoration.setOutSpacing(this, 15, 12, 15, 12)
        mainRvList.addItemDecoration(spacingDecoration)

        mainRvList.adapter = adapter
    }

    // 初始化数据源
    private fun initData() {
        // 普通按钮
        normalButtonsList.add(OrderActionBtnEntity(DELETE_TYPE, "支付", "#999999"))
        normalButtonsList.add(OrderActionBtnEntity(DELETE_TYPE, "在线咨询", "#999999"))
        normalButtonsList.add(OrderActionBtnEntity(DELETE_TYPE, "分享", "#999999"))
        normalButtonsList.add(OrderActionBtnEntity(MAKE_AN_SHARE_MORE_TYPE, "分享更多", "#999999"))
        // 普通按钮2
        normalButtonsList2.add(OrderActionBtnEntity(DELETE_TYPE, "支付", "#999999"))
        normalButtonsList2.add(OrderActionBtnEntity(DELETE_TYPE, "在线咨询", "#999999"))
        // 普通按钮3
        normalButtonsList3.add(OrderActionBtnEntity(DELETE_TYPE, "支付", "#999999"))
        normalButtonsList3.add(OrderActionBtnEntity(DELETE_TYPE, "分享", "#999999"))
        // 更多按钮
        moreButtonsList.add(OrderActionBtnEntity(DELETE_TYPE, "删除订单", "#999999"))
        moreButtonsList.add(OrderActionBtnEntity(GO_SHOPPING_CART_TYPE, "加入购物车", "#999999"))
        moreButtonsList.add(OrderActionBtnEntity(MAKE_AN_INVOICE_TYPE, "申请开票", "#999999"))
        // 更多按钮2
        moreButtonsList2.add(OrderActionBtnEntity(DELETE_TYPE, "删除订单", "#999999"))
        moreButtonsList2.add(OrderActionBtnEntity(MAKE_AN_INVOICE_TYPE, "申请开票", "#999999"))
        // 更多按钮3
        moreButtonsList3.add(OrderActionBtnEntity(DELETE_TYPE, "删除订单", "#999999"))

        dataList.add(OrderEntity("商品----1", "¥ 100.0 元", normalButtonsList, moreButtonsList))
        dataList.add(OrderEntity("商品----2", "¥ 10.0元", normalButtonsList2, moreButtonsList2))
        dataList.add(OrderEntity("商品----3", "¥11.0元", normalButtonsList3, moreButtonsList3))
        dataList.add(OrderEntity("商品----4", "¥ 1000.0元", normalButtonsList, moreButtonsList))
        dataList.add(OrderEntity("商品----5", "¥ 1000.0元", normalButtonsList, moreButtonsList))
        dataList.add(OrderEntity("商品----6", "¥ 1000.0元", normalButtonsList, moreButtonsList))
        dataList.add(OrderEntity("商品----7", "¥ 1000.0元", normalButtonsList, moreButtonsList))
    }


}

3、item_order.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@drawable/shape_solid_white_radius_4dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">

    <ImageView
        android:id="@+id/orderImg"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/ic_launcher_background"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/orderName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:textSize="16sp"
        app:layout_constraintLeft_toRightOf="@+id/orderImg"
        app:layout_constraintTop_toTopOf="@+id/orderImg"
        tools:text="大保健" />

    <TextView
        android:id="@+id/orderPrice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:textSize="12sp"
        app:layout_constraintBottom_toBottomOf="@+id/orderImg"
        app:layout_constraintLeft_toRightOf="@+id/orderImg"
        tools:text="¥100.0" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        app:layout_constraintTop_toBottomOf="@+id/orderImg">

        <TextView
            android:id="@+id/tv_moreBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="更多"
            android:textColor="#666666"
            android:textSize="16sp"
            android:visibility="visible" />

        <HorizontalScrollView
            android:fillViewport="true"
            android:scrollbars="none"
            android:layout_marginLeft="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <LinearLayout
                android:id="@+id/normalButtons"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="right"
                android:orientation="horizontal" />
        </HorizontalScrollView>

    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

4、MainRvAdapter ->>>>> RecyclerView.Adapter

public class MainRvAdapter extends RecyclerView.Adapter<MainRvAdapter.MoreActionHolder> {
    private List<OrderEntity> mData = new ArrayList<>();

    public MainRvAdapter(List<OrderEntity> mData, Context context) {
        this.mData.clear();
        this.mData.addAll(mData);
    }


    @Override
    public MoreActionHolder onCreateViewHolder(@NonNull @NotNull ViewGroup parent, int viewType) {
        View itemRoot = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_order, parent, false);
        return new MoreActionHolder(itemRoot);
    }

    @Override
    public void onBindViewHolder(MoreActionHolder holder, int position) {
        OrderEntity item = this.mData.get(position);
        holder.bind(item);
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    class MoreActionHolder extends RecyclerView.ViewHolder {
        private final TextView name;
        private final TextView price;
        private final TextView tv_moreBtn;
        private final LinearLayout normalBtnlay;

        public MoreActionHolder(@NonNull @NotNull View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.orderName);
            price = itemView.findViewById(R.id.orderPrice);
            tv_moreBtn = itemView.findViewById(R.id.tv_moreBtn);
            normalBtnlay = itemView.findViewById(R.id.normalButtons);
        }

        public void bind(OrderEntity item) {
            name.setText(item.getName());
            price.setText(item.getPrice());
            // ===============更多 中按钮===========================
            if (item.getExt_buttons() != null && item.getButtons().size() > 0) { // 存在就显示
                tv_moreBtn.setVisibility(View.VISIBLE);

                ActionMorePopWindow orderMorePopWindow = new ActionMorePopWindow(
                        itemView.getContext(),
                        item.getExt_buttons()
                );
                orderMorePopWindow.setOnItemMyListener(new ActionMorePopWindow.OnPopWindowItemListener() {
                    @Override
                    public void OnItemListener(int position, OrderActionBtnEntity orderActionEntity) {
                        performClicker(itemView.getContext(),orderActionEntity, orderActionEntity.getType());
                    }
                });
                tv_moreBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        orderMorePopWindow.showPopupWindow(tv_moreBtn);
                    }
                });

            } else {
                tv_moreBtn.setVisibility(View.GONE);
            }

            // =============== 普通按钮==============
            normalBtnlay.removeAllViews();
            if (item.getButtons() != null && item.getButtons().size() > 0) { // 存在普通按钮就加入linearLayout
                normalBtnlay.setVisibility(View.VISIBLE); // 显示
                for (int i = 0; i < item.getButtons().size(); i++) {
                    TextView normalBtn = createBtn(itemView.getContext(), item.getButtons().get(i));
                    normalBtnlay.addView(normalBtn);
                    int finalI = i;
                    normalBtn.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            performClicker(itemView.getContext(),item.getButtons().get(finalI), (Integer) normalBtn.getTag());
                        }
                    });
                }
            } else { // 不显示
                normalBtnlay.setVisibility(View.GONE);
            }
        }

        /**
         * @param context
         * @param buttonEntity
         * @return 动态创建普通类型的按钮
         */
        private TextView createBtn(Context context, OrderActionBtnEntity buttonEntity) {
            TextView tv = new TextView(context);
            tv.setText(buttonEntity.getName());
            tv.setTag(buttonEntity.getType());
            tv.setBackground(context.getResources().getDrawable(R.drawable.order_btn_normal_bg));
            FrameLayout.LayoutParams layoutParams =
                    new FrameLayout.LayoutParams(DensityUtil.INSTANCE.dp2px(75f), DensityUtil.INSTANCE.dp2px(30f));
            layoutParams.setMargins(DensityUtil.INSTANCE.dp2px(10f), 0, 0, 0);//4个参数按顺序分别是左上右下
            tv.setLayoutParams(layoutParams);
            tv.setGravity(Gravity.CENTER);
            tv.setPadding(10, 5, 10, 5);
            // 设置按钮的文字颜色和边框高亮颜色,不存在就是默认的灰色
            GradientDrawable gradientDrawable = (GradientDrawable) tv.getBackground();
            gradientDrawable.setStroke(1, Color.parseColor(buttonEntity.getColor()));//设置边框的宽度和颜色
            tv.setTextColor(Color.parseColor(buttonEntity.getColor()));
            return tv;
        }
    }

    private void performClicker(Context context, OrderActionBtnEntity entity, int type) {
        switch (type) {
            case MainActivity
                    .DELETE_TYPE:
                Toast.makeText(context, "点击了按钮:" + entity.getName(), Toast.LENGTH_SHORT).show();
            case MainActivity
                    .GO_SHOPPING_CART_TYPE:
                Toast.makeText(context, "点击了按钮:" + entity.getName(), Toast.LENGTH_SHORT).show();
            case MainActivity
                    .MAKE_AN_INVOICE_TYPE:
                Toast.makeText(context, "点击了按钮:" + entity.getName(), Toast.LENGTH_SHORT).show();

        }
    }

}

github地址

总结

绘制点9 图片需要注意规则:
1、左上控制拉伸,黑边之外不会拉伸
2 、右下控制内容显示的地方,黑边以为外padding

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-24 18:35:55  更:2021-12-24 18:37:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:39:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码