文档章节

自定义可显示多行的 Spinner

人生如歌
 人生如歌
发布于 2015/03/02 17:28
字数 913
阅读 441
收藏 11

效果图如下:

    为了增加按钮点击时的效果,此控件继承自 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
0
自定义Android的Spinner

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

kut
2011/08/31
0
5
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
3.2K
8
Android学习笔记(十二):Activity-Spinner

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

鉴客
2011/12/01
1K
0
Android Spinner 五步走

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

鉴客
2011/12/01
5.7K
2

没有更多内容

加载失败,请刷新页面

加载更多

自己手写一个 SpringMVC 框架

前端框架很多,但没有一个框架称霸,后端框架现在Spring已经完成大一统.所以学习Spring是Java程序员的必修课. Spring 框架对于 Java 后端程序员来说再熟悉不过了,以前只知道它用的反射实现的,...

别打我会飞
5分钟前
0
0
01-《Apache Tomcat 9》之文件索引

《Apache Tomcat 9》是《看Apache官方文档学英语》的第一个专栏!让我们一起在看文档的过程中学英语,在学英语的过程中夯实技术! Documentation Index - 文件索引 Introduction - 介绍 This...

飞鱼说编程
6分钟前
0
0
最近

20181016最近在熟悉业务 关于money的 要涉及到流程中转同步 这个点感觉 业务大于技术 关于业务性的内容 还是要把自己及时清零的好 我们需要好好的梳理下业务内容 业务作为导向 技术提供解决方...

JAVA码猿
16分钟前
0
0
JDK1.8HashMap源码分析

HashMap和Hashtable的主要区别是: 1. Hashtable是线程安全,而HashMap则非线程安全,Hashtable的实现方法里面大部分都添加了synchronized关键字来确保线程同步,因此相对而言HashMap性能会高...

小小明童鞋
25分钟前
14
0
以Redis为例,详谈分布式系统缓存的细枝末节

前言: 在分布式Web程序设计中,解决高并发以及内部解耦的关键技术离不开缓存和队列,而缓存角色类似计算机硬件中CPU的各级缓存。如今的业务规模稍大的互联网项目,即使在最初beta版的开发上...

Java干货分享
28分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部