干货一:通过自定义PopupWindow实现QQ菜单选项功能

干货一:通过自定义PopupWindow实现QQ菜单选项功能,第1张

概述概述我们在使用手机QQ时,点击菜单键,会d出如本案例说演示的效果图似的菜单选项。实现方式有很多种,在这里我们来演示下如何通过自定义PopupWindow的方式一步一步的实现如上效果。关于PopupWindow的基本知识点请查看PopupWindow分析UI部分shape的使用-cornerssolid等中间的使用Vi

概述

我们在使用手机QQ时,点击菜单键,会d出如本案例说演示的效果图似的菜单选项。


实现方式有很多种,在这里我们来演示下如何通过自定义PopupWindow的方式一步一步的实现如上效果。

关于PopupWindow的基本知识点请查看 PopupWindow

分析UI部分shape的使用-corners solID等中间的使用VIEw分割背景的处理……功能点响应点击事件–通过接口回调的方式点击外部,PopupWindow可消失……实现自定义PopupWindowUI编写位于父布局的底部距边框有一定的距离,根布局使用layout_margin即可

ListVIEw(四个圆角+白色背景) + VIEw分割(透明色) +底部文字(圆角+白色背景)

蓝色字体 居中显示(ListVIEw中的 在Item设置即可,底部文字设置gravity即可)

…….

布局文件如下所示:

List_popupwindow.xml

<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:ID="@+ID/ID_rl_relativeLayout"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    androID:layout_margin="16dp"    androID:padding="16dp">    <ListVIEw        androID:ID="@+ID/ID_lv_popupWindowListVIEw"        androID:layout_wIDth="match_parent"        androID:layout_height="wrap_content"        androID:layout_above="@+ID/vIEw"        androID:background="@drawable/bg_menu" />    <VIEw        androID:ID="@+ID/vIEw"        androID:layout_wIDth="match_parent"        androID:layout_height="20dp"        androID:layout_above="@+ID/ID_tv_bottom"        androID:background="@color/transparent" />    <TextVIEw        androID:ID="@+ID/ID_tv_bottom"        androID:layout_wIDth="match_parent"        androID:layout_height="50dp"        androID:layout_alignParentBottom="true"        androID:background="@drawable/bg_menu"        androID:gravity="center"        androID:text="取消"        androID:textcolor="@color/skyblue"        androID:textSize="20dp" />relativeLayout>

其中用到的几个背景xml如下,都在drawable目录下

bg_menu.xml

<shape xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:shape="rectangle">        <stroke androID:color="@color/transparent"        androID:wIDth="2dp"/>        <solID androID:color="@color/bg_white" />        <corners androID:radius="10dp" />shape>

自定义PopupWindow编写 +接口回调+监听Ontouch事件实现点击外部消失

加载自定义的xml文件,然后获取ListVIEw组件,设置adapter 即可显示UI布局。代码中的注释已经非常详细了,再此就不多涉及了。

import androID.content.Context;import androID.graphics.drawable.colorDrawable;import androID.vIEw.LayoutInflater;import androID.vIEw.MotionEvent;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.AdapterVIEw;import androID.Widget.ListVIEw;import androID.Widget.PopupWindow;import androID.Widget.TextVIEw;import com.turing.base.R;import com.turing.nutritIoUsSerial.ListPopupWindow.adapter.CustomPopupWindowAdpater;import com.turing.nutritIoUsSerial.ListPopupWindow.beans.PopupItemBean;import java.util.List;/** * MyApp * * @author Mr.Yang on 2016-04-25  10:12. * @version 1.0 * @desc */public class ListPopupWindow extends PopupWindow {    //上下文    private Context context;    //父视图    private VIEw parentVIEw;    //item数据源    private ListdataList;    //适配器    private CustomPopupWindowAdpater adapter;    //声明接口对象    private OnPopubItemClickListener popupItemListener;    private OnBottomTextVIEwClickListener bottomTextVIEwListener;    /**     * 定义接口用于PopupItem回调点击事件处理     */    public interface OnPopubItemClickListener {        voID onPopupItemClick(VIEw vIEw, int postion);    }    /**     * 定义接口用于底部TextVIEw回调点击事件处理     */    public interface OnBottomTextVIEwClickListener {        voID onBottomClick();    }    /**     * 构造函数     */    public ListPopupWindow(Context context,                           ListdataList,                           VIEw parentVIEw,                           OnPopubItemClickListener popupItemListener,                           OnBottomTextVIEwClickListener bottomTextVIEwListener) {        this.context = context;        this.dataList = dataList;        this.parentVIEw = parentVIEw;        this.popupItemListener = popupItemListener;        this.bottomTextVIEwListener = bottomTextVIEwListener;        initCustomPopupWindow();    }    /**     * 初始化自定义的PopupWindow     */    private voID initCustomPopupWindow() {        // 加载自定义布局文件,转化为组件        parentVIEw = LayoutInflater.from(context).inflate(R.layout.List_popupwindow, null);        // 设置显示的vIEw        setContentVIEw(parentVIEw);        // 初始化控件        ListVIEw lv = (ListVIEw) parentVIEw.findVIEwByID(R.ID.ID_lv_popupWindowListVIEw);        TextVIEw tv = (TextVIEw) parentVIEw.findVIEwByID(R.ID.ID_tv_bottom);        // 设置d出窗体的高        this.setWIDth(VIEwGroup.LayoutParams.MATCH_PARENT);        this.setHeight(VIEwGroup.LayoutParams.MATCH_PARENT);        // 设置d出窗体可点击        this.setFocusable(true);        // 设置SelectPicPopupWindowd出窗体的背景        this.setBackgroundDrawable(new colorDrawable(0xb0000000));        // vIEw添加OntouchListener监听判断获取触屏位置如果在布局外面则销毁d出框        parentVIEw.setontouchListener(new VIEw.OntouchListener() {            @OverrIDe            public boolean ontouch(VIEw v, MotionEvent event) {                // gettop VIEw自身的顶边到其父布局顶边的距离,因为是根目录所以为0                int height = parentVIEw.findVIEwByID(R.ID.ID_rl_relativeLayout).gettop();                // getY 点击事件距离控件顶边的举例                int y = (int) event.getY();                // 当抬起 并且 y>height时(也就是 只要不点击ListVIEw范围内),dismiss popupWindow                if (event.getAction() == MotionEvent.ACTION_UP) {                    if (y > height) {                        dismiss();                    }                }                return true;            }        });        // 更新位置和大小(不加这行代码也行)        update();        // 实例化适配器        adapter = new CustomPopupWindowAdpater(context, dataList);        // 设置适配器        lv.setAdapter(adapter);        // ListVIEw设置点击事件        lv.setonItemClickListener(new AdapterVIEw.OnItemClickListener() {            @OverrIDe            public voID onItemClick(AdapterVIEw parent, VIEw vIEw, int position, long ID) {                // 回调onPopupItemClick                popupItemListener.onPopupItemClick(vIEw, position);            }        });        // TextVIEw设置点击事件        tv.setonClickListener(new VIEw.OnClickListener() {            @OverrIDe            public voID onClick(VIEw v) {                // 回调onBottomClick                bottomTextVIEwListener.onBottomClick();            }        });    }}

CustomPopupWindowAdpater.java

import androID.content.Context;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.Widget.BaseAdapter;import androID.Widget.TextVIEw;import com.turing.base.R;import com.turing.nutritIoUsSerial.ListPopupWindow.beans.PopupItemBean;import java.util.List;/** * MyApp * * @author Mr.Yang on 2016-04-25  11:04. * @version 1.0 * @desc */public class CustomPopupWindowAdpater extends BaseAdapter {    private Context context;    private Listdatas;    private LayoutInflater layoutInflater;    /**     * 构造函数     */    public CustomPopupWindowAdpater(Context context, Listdatas) {        this.context = context;        this.datas = datas ;        layoutInflater = LayoutInflater.from(context);    }    @OverrIDe    public int getCount() {        return datas.size();    }    @OverrIDe    public Object getItem(int position) {        return datas.get(position);    }    @OverrIDe    public long getItemID(int position) {        return position;    }    @OverrIDe    public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) {        // 声明VIEwHolder        VIEwHolder vIEwHolder;        if (convertVIEw == null) {            // 加载Item布局,转换为VIEw布局            convertVIEw = layoutInflater.inflate(R.layout.popup_item, parent, false);            // 实例化VIEwHolder            vIEwHolder = new VIEwHolder();            // 查找组件赋值给VIEwHolder            vIEwHolder.textVIEw = (TextVIEw) convertVIEw.findVIEwByID(R.ID.ID_tv_popupItemText);            // 设置TAG            convertVIEw.setTag(vIEwHolder);        } else {            vIEwHolder = (VIEwHolder) convertVIEw.getTag();        }        // 设置Item中的值        vIEwHolder.textVIEw.setText(datas.get(position).getText()  );        return convertVIEw;    }    /**     * 对应Item布局中的组件     */    class VIEwHolder {        private TextVIEw textVIEw;    }}

调用

因为PopupWindow需要依赖父组件来显示,所以实例话PopupWindow的时候,传入根布局VIEw,实现接口回调Activity类实现自定义的两个接口,并传入到PopupWindow中。

import androID.os.Bundle;import androID.support.v7.app.AppCompatActivity;import androID.vIEw.Gravity;import androID.vIEw.VIEw;import androID.Widget.relativeLayout;import com.turing.base.R;import com.turing.base.utils.AlertUtil;import com.turing.nutritIoUsSerial.ListPopupWindow.beans.PopupItemBean;import com.turing.nutritIoUsSerial.ListPopupWindow.customPopupWindow.ListPopupWindow;import java.util.ArrayList;import java.util.List;public class ListPopupWindowDemoActivity extends AppCompatActivity implements ListPopupWindow.OnPopubItemClickListener, ListPopupWindow.OnBottomTextVIEwClickListener {    // 定义父VIEw即PopupWindow依赖浮动的VIEw    private relativeLayout relativeLayout;    private ListPopupWindow popWindow;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_List_popup_window_demo);        // 父VIEw        relativeLayout = (relativeLayout) findVIEwByID(R.ID.ID_rl_relativeLayout);    }    /**     * 按钮监听事件     *     * @param vIEw     */    public voID showCustomListPopupWindow(VIEw vIEw) {        // 展示数据集合        ListdataLists = new ArrayList<>();        // List集合中的数据        PopupItemBean itemBean1 = new PopupItemBean("版本更新");        PopupItemBean itemBean2 = new PopupItemBean("反馈");        PopupItemBean itemBean3 = new PopupItemBean("退出QQ");        // 添加到List集合中        dataLists.add(itemBean1);        dataLists.add(itemBean2);        dataLists.add(itemBean3);        // 实例化自定义ListPopupWindow        popWindow = new ListPopupWindow(ListPopupWindowDemoActivity.this,                dataLists, relativeLayout, this, this);        // 居中并且靠底部显示        popWindow.showAtLocation(relativeLayout, Gravity.CENTER | Gravity.BottOM, 0, 0);    }    @OverrIDe    public voID onBottomClick() {        popWindow.dismiss();        AlertUtil.showToastShort(ListPopupWindowDemoActivity.this, "点击取消");    }    @OverrIDe    public voID onPopupItemClick(VIEw vIEw, int postion) {        switch (postion) {            case 0:                AlertUtil.showToastShort(ListPopupWindowDemoActivity.this, String.valueOf(postion) + " 被点击");                break;            case 1:                AlertUtil.showToastShort(ListPopupWindowDemoActivity.this, String.valueOf(postion) + " 被点击");                break;            case 2:                AlertUtil.showToastShort(ListPopupWindowDemoActivity.this, String.valueOf(postion) + " 被点击");                break;            default:                break;        }    }}

总结

以上是内存溢出为你收集整理的干货一:通过自定义PopupWindow实现QQ菜单选项功能全部内容,希望文章能够帮你解决干货一:通过自定义PopupWindow实现QQ菜单选项功能所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/999707.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存