文档章节

自定义可显示多行的 Spinner

人生如歌
 人生如歌
发布于 2015/03/02 17:28
字数 913
阅读 425
收藏 11
点赞 0
评论 0

效果图如下:

    为了增加按钮点击时的效果,此控件继承自 LinearLayout,LinearLayout 中添加一个模样类似于 Spniner 的 Button,在点击 Button 的时候显示数据。自定义变量如下:

/**
  *  Dialog 模式
  */
 public static final int MODE_DIALOG = 0;
 /**
  * dropdown 模式
  */
 public static final int MODE_DROPDOWN = 1;
 /**
  * 默认选择 dropdown 模式
  */
 private static final int MODE_THEME = -1;
 private SpinnerPopup mPopup;// 两种 Popup 模式实现的同一接口
 private Button mSpinnerButton;// 默认Button
 private ListAdapter mAdapter;
 private int mTextColor;// 字体颜色
 private int mSelectedItemPosition;// 选中的位置

初始化,根据资源文件设置显示数据的模式:

 /**
  * 初始化
  * @param context
  * @param mode 显示数据的模式:下拉或者dialog
  */
 private void init(Context context, int mode) {
  this.setBackgroundResource(R.drawable.bg_textfield_default);// 设置背景
  /** 添加 Button */
  mSpinnerButton = new Button(context);
  mSpinnerButton.setBackgroundResource(R.drawable.selector_spinner);// 设置成下拉控件背景
  /** button只用一行显示 */
  mSpinnerButton.setEllipsize(TruncateAt.END);
  mSpinnerButton.setMaxLines(1);
  mSpinnerButton.setTextColor(mTextColor);// 字体颜色
  LinearLayout.LayoutParams params = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
  this.addView(mSpinnerButton, params);
  mSpinnerButton.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    if(mPopup != null)
     mPopup.show();// 点击 Button 显示 Popup
   }
  });
  switch (mode) {
  case MODE_DIALOG: {//Dialog 模式
   mPopup = new DialogPopup();
   break;
  }
  case MODE_DROPDOWN: {//下拉模式
   mPopup = new DropdownPopup(context);
   break;
  }
  }
  
 }

两种模式统一实现同一个接口:

 /**
  * 两种 Popup 模式实现同一接口
  */
 public interface SpinnerPopup {
  public void setAdapter(ListAdapter adapter);
  /**
   * 显示 popup
   */
  public void show();
  /**
   * 隐藏  popup
   */
  public void dismiss();
  /**
   * 
   * @return 如果 popup 已显示,返回 true, 否则返回 false
   */
  public boolean isShowing();
  
  /**
   * 设置 Popup ListView 的样式
   */
  public void setPopupListViewStyle(ListView listView);
  
 }

Dialog 模式实现的 Popup:

 /**
  * Dialog Popup
 *@author liuyinjun
 
 * @date 2015-2-9
  */
 private class DialogPopup implements SpinnerPopup, DialogInterface.OnClickListener {
  private AlertDialog mPopup;
  private ListAdapter mListAdapter;
  
  public void dismiss() {
   if(mPopup == null)
    return;
   mPopup.dismiss();
   mPopup = null;
  }
  public boolean isShowing() {
   return mPopup != null ? mPopup.isShowing() : false;
  }
  public void setAdapter(ListAdapter adapter) {
   this.mListAdapter = adapter;
  }
  public void show() {
   AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
   mPopup = builder.setSingleChoiceItems(mListAdapter, getSelectedItemPosition(), this).create();
   final ListView listView = mPopup.getListView();
   setPopupListViewStyle(listView);
   if(mPopup != null)
    mPopup.show();
  }
  @Override
  public void onClick(DialogInterface dialog, int which) {
   setSelection(which);
  }

  @Override
  public void setPopupListViewStyle(ListView listView) {
   if(listView == null)
    return;
   listView.setBackgroundResource(R.drawable.bg_spinner_white_shadow);
   listView.setCacheColorHint(Color.TRANSPARENT);
   listView.setDivider(getResources().getDrawable(R.drawable.list_view_divider_line));
   listView.setDividerHeight(1);
  }

 }

下拉模式实现的 Popup:

 /**
  * 下拉 Popup
 *@author liuyinjun
 
 * @date 2015-2-9
  */
 private class DropdownPopup extends PopupWindow implements SpinnerPopup {
  private ListView mListView;
  public DropdownPopup(Context context) {
   LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   View contentView = inflater.inflate(R.layout.spinner_shared_list, null);
   this.setContentView(contentView);
   this.setWidth(LayoutParams.FILL_PARENT);
   this.setHeight(LayoutParams.WRAP_CONTENT);
   this.setTouchable(true);
   this.setFocusable(true);
   this.setOutsideTouchable(true);
   this.setBackgroundDrawable(new BitmapDrawable());
   this.setAnimationStyle(R.style.SpinnerAnimation);// 设置进入进出动画
   mListView = (ListView) contentView.findViewById(R.id.spinner_shared_listview);
   setPopupListViewStyle(mListView);
   // 下拉后点击 item 事件
   mListView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
     setSelection(position);
    }
   });
  }
  @Override
  public void setAdapter(ListAdapter adapter) {
   if (mListView != null)
    mListView.setAdapter(adapter);
  }
  @Override
  public void show() {
   showAsDropDown(CustomSpinner.this, 0, 0);//显示在当前控件之下
  }
  @Override
  public void setPopupListViewStyle(ListView listView) {
   if(listView == null)
    return;
   listView.setBackgroundResource(R.drawable.bg_spinner_white_shadow);
   listView.setCacheColorHint(Color.TRANSPARENT);
   listView.setDivider(getResources().getDrawable(R.drawable.list_view_divider_line));
   listView.setDividerHeight(1);
  }
 }

类似于 Spinner,设置适配器方法如下:

 public void setAdapter(ListAdapter adapter) {
  this.mAdapter = adapter;
  if (mPopup != null) {
   mPopup.setAdapter(adapter);
  }
  setSelection(0);//默认选中第一个
 }

根据位置选中数据,可作定位用:

 /**
  * 根据位置选中数据
  * 
  * @param position
  */
 public void setSelection(int position) {
  if(mAdapter == null)
    throw new UnsupportedOperationException("请先设置适配器");
  this.mSelectedItemPosition = position;
  mSpinnerButton.setText(mAdapter.getItem(position).toString());// 设置Button显示选中文本
  if (mPopup != null && mPopup.isShowing())
   mPopup.dismiss();
 }

自定义属性定义了:1、两种模式的选择;2、选择文本显示的字体颜色

<declare-styleable name="CustomSpinner">
        <attr name="spinnerMode">
            <enum name="dialog" value="0" />
            <enum name="dropdown" value="1" />
        </attr>
        <attr name="textColor" format="color" />
    </declare-styleable>

至此,关键代码已贴出,关键是 PopupWindow 与 AlertDialog 的运用。此控件的用法非常类似于 Spinner,完整代码请看自定义可显示多行的 Spinner

最近在运营一个有关反脆弱成长的个人公众号,欢迎关注

© 著作权归作者所有

共有 人打赏支持
人生如歌
粉丝 7
博文 15
码字总数 7993
作品 0
深圳
程序员
android自定义spinner,使用AppCompatTextView+PopupWindow 实现下拉选择的功能

自定义spinner 自定义spinner,使用AppCompatTextView+PopupWindow 实现下拉选择的功能,代码简单,几个类 感谢 https://github.com/arcadefire/nice-spinner,本项目是对其的优化与扩展 1、...

陶海理 ⋅ 01/16 ⋅ 0

Liger UI v1.1.0 发布,基于jQuery的UI框架

API: http://api.ligerui.com/ 演示地址:http://demo.ligerui.com/ 源码下载:http://ligerui.googlecode.com/ 技术支持:http://www.cnblogs.com/leoxie2011/ V1.1.0更新记录: 表格 [需求]......

leeoo ⋅ 2011/11/23 ⋅ 8

自定义Android的Spinner

刚接触Android平台编程不久,被烂教材整得头晕。 有一个关于Spinner扩展的问题,问题是,怎么把弹出来的菜单自定义。当然,书上是没有告诉你的,它们压根就不知道那个和ArrayAdapter相关的两...

kut ⋅ 2011/08/31 ⋅ 5

Android学习笔记(十二):Activity-Spinner

例子一:Spinner的基本实现方法 步骤一:编写Android XML文件

鉴客 ⋅ 2011/12/01 ⋅ 0

自定义 Spinner 显示的样式(修改颜色等)

这里指的Spinner显示的样式,并不是指在点击Spinner后弹出的选择框的样式,而是直接显示在屏幕上的那个按钮的样式。我有个项目需要使用Spinner,但使用默认的样式又与现有UI不匹配,需要稍稍...

鉴客 ⋅ 2011/12/14 ⋅ 4

Android Spinner 五步走

自定义Spinner(下拉列表)五步走,原文出处:http://yilee.info/android-spinner.html 在Android的UI开发中,Spinner(下拉列表)总是可以用到的,一个简单的自定义Spinner制作我们只需要记住这...

鉴客 ⋅ 2011/12/01 ⋅ 2

Android基础教程(九)之自定义下拉菜单模式----Spinner与setDropDownViewResource的应用

大家好,我们这一节讲一下Android下的下拉菜单Spinner,就像是Swing的Combobox,html的<select>,由于手机画面有限,要在有限的范围选择项目,下拉菜单是比较好的选择. Android提供的Spinner Widge...

神勇小白鼠 ⋅ 2011/01/06 ⋅ 0

自定义下拉菜单模式Spinner

Spinner 下拉菜单 setDropDownViewResource xml方式定义下拉列表菜单要显示的模样,类似于填充器 package com.example.demo; import java.util.ResourceBundle.Control; import android.os.B......

chenruibing ⋅ 2015/05/29 ⋅ 1

Spinner+GridView 监听 求解。。。。

怎样给Spinner 一个监听 当选择下拉框类型后 下面的图片 会显示 对应的 图片啊?现在显示的是全部的。我定义的 数据库 图片字段名为 num 。SD卡图片名跟数据图片名一样。我的Adapter 是自定义...

黛曦葛溪 ⋅ 2012/06/05 ⋅ 10

Android 之 下拉框(Spinner)的简单使用

1. 工程的layout.xml文件如下:声明一个TextView控件和一个Spinner控件

晨曦之光 ⋅ 2012/03/01 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Linux中的端口大全

1 被LANA定义的端口 端口 名称 描述 1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接了的端口的系统状态 13 d...

寰宇01 ⋅ 21分钟前 ⋅ 0

Confluence 6 如何备份存储文件和页面信息

备份的 ZIP 文件包含有 entities.xml,这个 XML 文件包含有 Confluence 的所有页面内容和存储附件的目录。 备份 Zip 文件结构 页面的附件是存储在附件存储目录中的,通过页面和附件 ID 进行识...

honeymose ⋅ 24分钟前 ⋅ 0

【每天一个JQuery特效】根据状态确定是否滑入或滑出被选元素

主要效果: 本文主要采用slideToggle()方法实现以一行代码同时实现以展开或收缩的方式显示或隐藏被选元素。 主要代码如下: <!DOCTYPE html><html><head><meta charset="UTF-8">...

Rhymo-Wu ⋅ 27分钟前 ⋅ 0

度量.net framework 迁移到.net core的工作量

把现有的.net framework程序迁移到.net core上,是一个非常复杂的工作,特别是一些API在两个平台上还不能同时支持。两个类库的差异性,通过人工很难识别全。好在微软的工程师们考虑到了我们顾...

李朝强 ⋅ 33分钟前 ⋅ 0

请不要在“微服务”的狂热中迷失自我!

微服务在过去几年一直是一个非常热门的话题(附录1)。何为“微服务的疯狂”,举个例子: 众所周知,Netflix在DevOps上的表现非常棒。Netfix可以做微服务。因此:如果我做微服务,我也将非常...

harries ⋅ 34分钟前 ⋅ 0

oAuth2 升级Spring Cloud Finchley.RELEASE踩坑分享

背景 6.19号,spring团队发布了期待已久的 Spring Cloud Finchley.RELEASE 版本。 重要变化: 基于Spring Boot 2.0.X 不兼容 Spring Boot 1.5.X 期间踩过几个坑,分享出来给大伙,主要是关于...

冷冷gg ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 理发师小姐姐的魔法

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @冰冰棒- :分享田馥甄的单曲《My Love》 《My Love》- 田馥甄 手机党少年们想听歌,请使劲儿戳(这里) @Li-Wang :哎,头发又长了。。。又要...

小小编辑 ⋅ 今天 ⋅ 9

Kafka1.0.X_消费者API详解2

偏移量由消费者管理 kafka Consumer Api还提供了自己存储offset的功能,将offset和data做到原子性,可以让消费具有Exactly Once 的语义,比kafka默认的At-least Once更强大 消费者从指定分区...

特拉仔 ⋅ 今天 ⋅ 0

NEO智能合约之发布和升级(二)

接NEO智能合约之发布和升级(一),我们接下来说说智能合约的升级功能。 一 准备工作 合约的升级需要在合约内预先设置好升级接口,以方便在升级时调用。接下来我们对NEO智能合约之发布和升级...

红烧飞鱼 ⋅ 今天 ⋅ 0

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部