Android RecyclerView实现下拉列表功能

现在市面上的很多的应用,都带有下拉列表的功能,将所有选项都放在下拉列表中,当用户点击选择的时候,弹出所有的选项,用户选择一项后,下拉列表自动隐藏,很多下拉列表都是用ListView + PopupWindow来实现的,由于Google推出了替代ListView的RecyclerView,所以简单实现一下:

MainActivity.java

package com.jackie.countdowntimer; 

import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.PopupWindow; 

import java.util.ArrayList;
import java.util.List; 

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  private EditText mNumberEditText;
  private ImageButton mSelectImageButton;
  private PopupWindow mPopupWindow;
  private RecyclerView mRecyclerView;
  private RecyclerViewAdapter mRecyclerViewAdapter;
  private List<String> mNumberList; 

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
            .setAction("Action", null).show();
      }
    }); 

    //初始化数据
    mNumberList = new ArrayList<>();
    for (int i = 0; i < 30; i++) {
      mNumberList.add("1000000" + i);
    } 

    mNumberEditText = (EditText) findViewById(R.id.number);
    mSelectImageButton = (ImageButton) findViewById(R.id.select_number);
    mSelectImageButton.setOnClickListener(this);
  } 

  @Override
  public void onClick(View v) {
    switch (v.getId()) {
      case R.id.select_number:
        showSelectNumberPopupWindow();
        break;
    }
  } 

  /**
   * 弹出选择号码的对话框
   */
  private void showSelectNumberPopupWindow() {
    initRecyclerView(); 

    mPopupWindow = new PopupWindow(mRecyclerView, mNumberEditText.getWidth() - 4, 200);
    mPopupWindow.setOutsideTouchable(true);   // 设置外部可以被点击
    mPopupWindow.setBackgroundDrawable(new BitmapDrawable()); 

    mPopupWindow.setFocusable(true);    // 使PopupWindow可以获得焦点
    // 显示在输入框的左下角
    mPopupWindow.showAsDropDown(mNumberEditText, 2, -5);
  } 

  /**
   * 初始化RecyclerView,模仿ListView下拉列表的效果
   */
  private void initRecyclerView(){
    mRecyclerView = new RecyclerView(this);
    //设置布局管理器
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setBackgroundResource(R.drawable.background); 

    //设置Adapter
    mRecyclerViewAdapter = new RecyclerViewAdapter(this, mNumberList);
    mRecyclerView.setAdapter(mRecyclerViewAdapter); 

    //设置点击事件
    mRecyclerViewAdapter.setOnItemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
      @Override
      public void onItemClick(View view, int position) {
        mNumberEditText.setText(mNumberList.get(position));
        mNumberEditText.setSelection(mNumberEditText.getText().toString().length());
        mPopupWindow.dismiss();
      }
    }); 

    //添加分割线
    mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
  }
 } 

RecyclerViewAdapter.java

package com.jackie.countdowntimer; 

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.TextView; 

import java.util.List; 

/**
 * Created by Jackie on 2015/12/18.
 * RecyclerView Adapter
 */
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
  private OnItemClickListener mOnItemClickListener;
  private Context mContext;
  private List<String> mNumberList; 

  public RecyclerViewAdapter(Context context, List<String> numberList) {
    this.mContext = context;
    this.mNumberList = numberList;
  } 

  public interface OnItemClickListener {
    void onItemClick(View view, int position);
  } 

  public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    this.mOnItemClickListener = onItemClickListener;
  } 

  @Override
  public RecyclerViewAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    RecyclerViewHolder holder = new RecyclerViewHolder(LayoutInflater.from(mContext).inflate(R.layout.number_item, parent, false));
    return holder;
  } 

  @Override
  public void onBindViewHolder(final RecyclerViewAdapter.RecyclerViewHolder holder, final int position) {
    holder.numberTextView.setText(mNumberList.get(position));
    // 如果设置了回调,则设置点击事件
    if (mOnItemClickListener != null) {
      holder.numberTextView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          mOnItemClickListener.onItemClick(holder.itemView, holder.getLayoutPosition());
        }
      });
    } 

    holder.deleteImageButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        mNumberList.remove(position);
        //通知刷新
        notifyItemRemoved(position);
      }
    });
  } 

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

  public class RecyclerViewHolder extends RecyclerView.ViewHolder {
    TextView numberTextView;
    ImageButton deleteImageButton; 

    public RecyclerViewHolder(View itemView) {
      super(itemView);
      numberTextView = (TextView) itemView.findViewById(R.id.number_item);
      deleteImageButton = (ImageButton) itemView.findViewById(R.id.number_item_delete);
    }
  }
} 

DividerItemDecoration.java

package com.jackie.countdowntimer; 

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * limitations under the License.
 */ 

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View; 

/**
 * This class is from the v7 samples of the Android SDK. It's not by me!
 * <p/>
 * See the license above for details.
 */
public class DividerItemDecoration extends RecyclerView.ItemDecoration { 

  private static final int[] ATTRS = new int[]{
      android.R.attr.listDivider
  }; 

  public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; 

  public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; 

  private Drawable mDivider; 

  private int mOrientation; 

  public DividerItemDecoration(Context context, int orientation) {
    final TypedArray a = context.obtainStyledAttributes(ATTRS);
    mDivider = a.getDrawable(0);
    a.recycle();
    setOrientation(orientation);
  } 

  public void setOrientation(int orientation) {
    if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
      throw new IllegalArgumentException("invalid orientation");
    }
    mOrientation = orientation;
  } 

  @Override
  public void onDraw(Canvas c, RecyclerView parent) {
    if (mOrientation == VERTICAL_LIST) {
      drawVertical(c, parent);
    } else {
      drawHorizontal(c, parent);
    }
  } 

  public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight(); 

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
      final View child = parent.getChildAt(i);
      android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
      final int top = child.getBottom() + params.bottomMargin;
      final int bottom = top + mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }
  } 

  public void drawHorizontal(Canvas c, RecyclerView parent) {
    final int top = parent.getPaddingTop();
    final int bottom = parent.getHeight() - parent.getPaddingBottom(); 

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
      final View child = parent.getChildAt(i);
      final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
      final int left = child.getRight() + params.rightMargin;
      final int right = left + mDivider.getIntrinsicHeight();
      mDivider.setBounds(left, top, right, bottom);
      mDivider.draw(c);
    }
  } 

  @Override
  public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
    if (mOrientation == VERTICAL_LIST) {
      outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
    } else {
      outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
    }
  }
}

效果图如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android下拉列表(Spinner)效果(使用C#和Java分别实现)

    效果如下: C#实现代码 using Android.App; using Android.OS; using Android.Widget; namespace SpinnerDemo { [Activity(Label = "@string/ApplicationName", MainLauncher = true, Icon = "@drawable/icon")] public class MainActivity : Activity { private

  • Android组件实现列表选择框功能

    android提供的列表选择框(Spinner)相当于web端用户注册时的选择下拉框,比如注册候选择省份城市等.如下图便是一个列表选择框 下拉列表的列表选择项能够通过xml文件的android:entries属性指定,或是在java代码中导入,属性android:prompt是列表项的标题. 一    列表项数据: 实际运用当中,很多下拉列表项的数据实际是可知的,可以放在xml资源文件中.这时,开发者可以通过xml属性进行指定数据. 除了资源文件之外,开发者还能够使用适配器适配数据源.(适配器:

  • Android列表选择框Spinner使用方法详解

    安卓提供的列表选择框(Spinner)相当于web端用户注册时的选择下拉框,比如注册候选择省份城市等.如下图便是一个列表选择框 下拉列表的列表选择项能够通过xml文件的android:entries属性指定,或是在java代码中导入,属性android:prompt是列表项的标题. 一 列表项数据 实际运用当中,很多下拉列表项的数据实际是可知的,可以放在xml资源文件中.这时,开发者可以通过xml属性进行指定数据. 除了资源文件之外,开发者还能够使用适配器适配数据源.(适配器:如果您的电脑不能接

  • Android自定义ViewGroup实现带箭头的圆角矩形菜单

    本文和大家一起做一个带箭头的圆角矩形菜单,大概长下面这个样子: 要求顶上的箭头要对准菜单锚点,菜单项按压反色,菜单背景色和按压色可配置. 最简单的做法就是让UX给个三角形的图片往上一贴,但是转念一想这样是不是太low了点,而且不同分辨率也不太好适配,干脆自定义一个ViewGroup吧! 自定义ViewGroup其实很简单,基本都是按一定的套路来的. 一.定义一个attrs.xml 就是声明一下你的这个自定义View有哪些可配置的属性,将来使用的时候可以自由配置.这里声明了7个属性,分别是:箭头宽

  • Android仿微信实现下拉列表

    本文要实现微信6.1中点击顶部菜单栏的"+"号按钮时,会弹出一个列表框.这里用的了Activity实现,其实最好的方法可以用ActionBar,不过这货好像只支持3.0以后的版本.本文的接上文Android仿微信底部菜单栏+顶部菜单栏. 效果 一.仿微信下拉列表布局pop_dialog.xml <?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android

  • Android实现三级联动下拉框 下拉列表spinner的实例代码

    主要实现办法:动态加载各级下拉值的适配器 在监听本级下拉框,当本级下拉框的选中值改变时,随之修改下级的适配器的绑定值              XML布局: 复制代码 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_w

  • Android自定义Spinner下拉列表(使用ArrayAdapter和自定义Adapter实现)

    今天学习了Spinner组件的使用,非常好用的一款组件,相当于从下拉列表中选择项目,今天收获颇多,下面给大家演示一下Spinner的使用(分别使用ArrayAdapter和自定义Adapter实现),具体内容如下. (一):使用ArrayAdapter进行适配数据: ①:首先定义一个布局文件: <span style="font-size:16px;"><?xml version="1.0" encoding="utf-8"?&

  • Android下拉列表spinner的实例代码

    spinner组件有点类型于HTML中的下拉框<Select></select>的样子,让用户每次从下拉框中选取一个,本文为大家分享了Android下拉列表spinner的具体实现代码,供大家参考,具体内容如下 mian.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.c

  • Android下拉列表选项框及指示箭头动画

    android原生的Spinner提供了下拉列表选项框,但在一些流行的APP中,原生的Spinner似乎不太受待见,而通常会有下图所示的下拉列表选项框: 初始化状态: 点击弹出下拉选择选项框: 选中后: 注意那个指示箭头,如果把这个控件写的比较精细的话,在下拉-选择-复位过程中箭头是应该有动画旋转效果的. 这种样式的选择框实现方案很多,并且常见.常用,我自己写了一个,我写的这个例子的代码运行结果就是上图所示. 首先是MainActivity.Java: package zhangphil.app

  • android中一些特殊字符(如:←↑→↓等箭头符号)的Unicode码值

    在项目中,有时候在一些控件(如Button.TextView)中要添加一些符号,如下图所示:                         这个时候可以使用图片的方式来显示,不过这些可以直接使用Unicode码就直接显示出来了. 4个箭头图标的代码如下: <RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight=&

随机推荐