Android自定义组件之ListPopWindow

简介: 版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/50582900 最近小编在学习IOS开发,感触颇深,看到了iOS里面封装了好多组件,很多组件都是iOS自带的,相信一般的小公司的产品经理都是按照iOS的交互来设计UI,而且还要求Android要和iOS统一风格,这让Android开发人员很头痛,iOS自带组件很容易实现,而Android可能需要重写控件去配合iOS的效果。
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/50582900

最近小编在学习IOS开发,感触颇深,看到了iOS里面封装了好多组件,很多组件都是iOS自带的,相信一般的小公司的产品经理都是按照iOS的交互来设计UI,而且还要求Android要和iOS统一风格,这让Android开发人员很头痛,iOS自带组件很容易实现,而Android可能需要重写控件去配合iOS的效果。其实这样必然会导致性能的小将,或有些许的卡顿。小编个人认为,按照各自系统的风格和规范进行设计才能把自己的优点发挥到最大化。
下面就引出了今天的主题,自定义组件ListPopWindow,iOS中,这个效果是自带的。PopWindow可以说在项目里用的比较多的了,可能有n处要用到PopWindow,那么自定义一个PopWindow,到处来用更方便一些。
先看一下效果:
这里写图片描述
效果就是这样,看一下实现,其实也没多难,就是想开源出来供小伙伴们使用,如有不合理地方,希望大家多多指正。

1.自定义PopWindow

首先我们分析一下,这样的效果肯定是一个PopWindow嵌套着listview,而上面的title、和下面的cancel是两个文本框,实现起来也比较简单。
然后我们在PopWindow中声明两个接口,用来回调cancel和item的点击事件

public interface  OnPopItemClickListener{
        void onPopItemClick(View view,int position);
    }

    public interface OnBottomTextviewClickListener{
        void onBottomClick();
    }

然后再设置一些PopWindow的一些属性

parentView = LayoutInflater.from(context).inflate(R.layout.list_popwindow,null);
        setContentView(parentView);
        lv = (ListView) parentView.findViewById(R.id.lv_popwindow);
        //设置弹出窗体的高
        this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        //设置弹出窗体可点击
        this.setFocusable(true);
        //实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0xb0000000);
        //设置SelectPicPopupWindow弹出窗体的背景
        this.setBackgroundDrawable(dw);

看一下整体的代码吧:

/**
 * Created by Hankkin on 16/1/25.
 */
public class ListPopWindow extends PopupWindow{

    private Context context;        //上下文
    private View parentView;        //父视图
    private List<PopBean> dataList; //item数据源
    private OnPopItemClickListener listener;    //item点击接口
    private ListView lv;    //item列表视图
    private View viewTop;   //title视图   
    private String topText,bottomText;  //title文字,bottom文字
    private TextView tvTop,tvBottom;    //title文本,bottom文本
    private PopWindowAdapter adapter;   //适配器
    private OnBottomTextviewClickListener bottomListener;//底部点击接口


    public interface  OnPopItemClickListener{
        void onPopItemClick(View view,int position);
    }

    public interface OnBottomTextviewClickListener{
        void onBottomClick();
    }

    public ListPopWindow(Context context,OnPopItemClickListener listener,OnBottomTextviewClickListener bottomListener,
                         View parentView,List<PopBean> dataList,String bottomText,String topText){
        this.context = context;
        this.listener = listener;
        this.parentView = parentView;
        this.dataList = dataList;
        this.bottomListener = bottomListener;
        this.topText = topText;
        this.bottomText = bottomText;

        initViews();
    }


    private void initViews(){
        parentView = LayoutInflater.from(context).inflate(R.layout.list_popwindow,null);
        setContentView(parentView);
        lv = (ListView) parentView.findViewById(R.id.lv_popwindow);
        //设置弹出窗体的高
        this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        this.setHeight(ViewGroup.LayoutParams.MATCH_PARENT);
        //设置弹出窗体可点击
        this.setFocusable(true);
        //实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0xb0000000);
        //设置SelectPicPopupWindow弹出窗体的背景
        this.setBackgroundDrawable(dw);

        //view添加OnTouchListener监听判断获取触屏位置如果在布局外面则销毁弹出框
        parentView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                int height = parentView.findViewById(R.id.ll_bottom).getTop();
                int y = (int) event.getY();
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (y > height) {
                        dismiss();
                    }
                }
                return true;
            }
        });

        update();
        viewTop = parentView.findViewById(R.id.view_line1);
        tvBottom = (TextView) parentView.findViewById(R.id.tv_popwindow_bottom);
        tvTop = (TextView) parentView.findViewById(R.id.tv_popwindow_first);
        adapter = new PopWindowAdapter(context,dataList,false);
        lv.setAdapter(adapter);

        if (!TextUtils.isEmpty(topText)){
            tvTop.setVisibility(View.VISIBLE);
            tvTop.setText(topText);
            viewTop.setVisibility(View.VISIBLE);
        }
        else {
            tvTop.setVisibility(View.GONE);
            viewTop.setVisibility(View.GONE);
        }

        if (!TextUtils.isEmpty(bottomText)){
            tvBottom.setVisibility(View.VISIBLE);
            tvBottom.setText(bottomText);
        }
        else {
            tvBottom.setVisibility(View.GONE);
        }

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                listener.onPopItemClick(view, i);
            }
        });

        tvBottom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bottomListener.onBottomClick();
            }
        });

    }

}

2.看一些item的bean

这里我就声明了title和图片的id

package com.hankkin.library;

/**
 * Created by Hankkin on 16/1/25.
 */
public class PopBean {
    private String title;
    private int icon_res;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getIcon_res() {
        return icon_res;
    }

    public void setIcon_res(int icon_res) {
        this.icon_res = icon_res;
    }

    public PopBean(String title, int icon_res) {
        this.title = title;
        this.icon_res = icon_res;
    }
}

3.自定义adapter适配器

这里面可能要注意的就是item的背景设置,有的是上半部分圆角、有的是下半部分圆角,特殊处理一下

@Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder;
        if (view == null) {
            view = inflater.inflate(R.layout.listview_popwindow_item, null);
            holder = new ViewHolder();
            holder.tv_name = (TextView) view.findViewById(R.id.tv_title);
            holder.v_line = (View) view.findViewById(R.id.v_line);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }

        holder.tv_name.setText(dataList.get(i).getTitle());


        if (dataList.size() - 1 == i) {
            holder.v_line.setVisibility(View.INVISIBLE);
            holder.tv_name.setBackground(context.getResources().getDrawable(R.drawable.selector_bottom_half));
        } else {
            holder.v_line.setVisibility(View.VISIBLE);
            holder.tv_name.setBackground(context.getResources().getDrawable(R.drawable.list_gray_item));
        }
        return view;
    }

最后看一下调用

Activity需要实现item接口(OnPopItemClickListener)和底部按钮接口(OnBottomTextviewClickListener)

public void show(View view){
        List<PopBean> pops = new ArrayList<>();
        for (int i=0;i<5;i++){
            PopBean pop = new PopBean("item"+i,0);
            pops.add(pop);
        }
        popWindow = new ListPopWindow(MainActivity.this,this,this,rl,pops,"cancel","title");
        popWindow.showAtLocation(rl, Gravity.CENTER| Gravity.BOTTOM,0,0);
    }

最后小编附上github源码地址,小伙伴们可以直接用哦。
https://github.com/Hankkin/ListPopwidowDemo

相关文章
|
3月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
55 1
|
3月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
4月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
53 3
|
4月前
|
存储 Android开发 开发者
深入理解安卓应用开发的核心组件
【10月更文挑战第8天】探索Android应用开发的精髓,本文带你了解安卓核心组件的奥秘,包括Activity、Service、BroadcastReceiver和ContentProvider。我们将通过代码示例,揭示这些组件如何协同工作,构建出功能强大且响应迅速的应用程序。无论你是初学者还是资深开发者,这篇文章都将为你提供新的视角和深度知识。
|
4月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
151 0
|
6月前
|
供应链 物联网 区块链
未来触手可及:探索新兴技术的趋势与应用安卓开发中的自定义视图:从基础到进阶
【8月更文挑战第30天】随着科技的飞速发展,新兴技术如区块链、物联网和虚拟现实正在重塑我们的世界。本文将深入探讨这些技术的发展趋势和应用场景,带你领略未来的可能性。
|
2月前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
3月前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
3月前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
68 5
|
4月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 3
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 7
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Android学习自定义View(四)——继承控件(滑动时ListView的Item出现删除按钮)