一:前言
本人參考部落格:http://blog.csdn.net/jdsjlzx/article/details/41316417 最近在弄一個下拉框,發現android自帶的很難實作我的功能,于是去網上找到一份demo,但是發現沒有封裝的好,并且還有很多重複的代碼,于是我在這位前輩的基礎上進行了修改.并且重新進行了封裝,代碼變得簡單,并且具有可讀性.
二:實作原理
1.就是一個textview 弄一個弧形的背景圖檔,然後設定一個點選事件.
2.點選textview之後顯示一個popupwindow,popupwindow是自定義的,裡面顯示一個listview.listview也設定了左邊.右邊.底部的邊框.
三:效果圖如下

四:代碼實作:
1).mainactivity.java 程式入口,初始化資料,初始化自定義popupwindow,textview點選之後顯示popupwindow,處理listview的點選事件.
/**
* 主activity 用來實作popupwindow
* @author ansen
*/
public class mainactivity extends activity {
private spinerpopwindow<string> mspinerpopwindow;
private list<string> list;
private textview tvvalue;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
initdata();
tvvalue = (textview) findviewbyid(r.id.tv_value);
tvvalue.setonclicklistener(clicklistener);
mspinerpopwindow = new spinerpopwindow<string>(this, list,itemclicklistener);
mspinerpopwindow.setondismisslistener(dismisslistener);
}
/**
* 監聽popupwindow取消
*/
private ondismisslistener dismisslistener=new ondismisslistener() {
@override
public void ondismiss() {
settextimage(r.drawable.icon_down);
}
};
* popupwindow顯示的listview的item點選事件
private onitemclicklistener itemclicklistener = new onitemclicklistener() {
public void onitemclick(adapterview<?> parent, view view, int position,long id) {
mspinerpopwindow.dismiss();
tvvalue.settext(list.get(position));
toast.maketext(mainactivity.this, "點選了:" + list.get(position),toast.length_long).show();
* 顯示popupwindow
private onclicklistener clicklistener = new onclicklistener() {
public void onclick(view v) {
switch (v.getid()) {
case r.id.tv_value:
mspinerpopwindow.setwidth(tvvalue.getwidth());
mspinerpopwindow.showasdropdown(tvvalue);
settextimage(r.drawable.icon_up);
break;
}
* 初始化資料
private void initdata() {
list = new arraylist<string>();
for (int i = 0; i < 5; i++) {
list.add("test:" + i);
* 給textview右邊設定圖檔
* @param resid
private void settextimage(int resid) {
drawable drawable = getresources().getdrawable(resid);
drawable.setbounds(0, 0, drawable.getminimumwidth(),drawable.getminimumheight());// 必須設定圖檔大小,否則不顯示
tvvalue.setcompounddrawables(null, null, drawable, null);
}
2).activity_main.xml 這個檔案也沒啥好說的 就是兩個textview。
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<linearlayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal">
<textview
android:id="@+id/tv_value"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/shape_help_category_tv_bg"
android:drawableright="@drawable/icon_down"
android:padding="10dp"
android:textcolor="@color/content_color"
android:text="請選擇父類别"
android:textsize="20sp"/>
android:layout_marginleft="5dp"
android:text="請選擇子類别"
android:textsize="20sp" />
</linearlayout>
</linearlayout>
3).spinerpopwindow.java 自定義popupwindow類 初始化popupwindow顯示的布局,以及一些參數,并且給listview設定擴充卡
* 自定義popupwindow 主要用來顯示listview
* @author ansen
* @param <t>
* @create time 2015-11-3
public class spinerpopwindow<t> extends popupwindow {
private layoutinflater inflater;
private listview mlistview;
private list<t> list;
private myadapter madapter;
public spinerpopwindow(context context,list<t> list,onitemclicklistener clicklistener) {
super(context);
inflater=layoutinflater.from(context);
this.list=list;
init(clicklistener);
private void init(onitemclicklistener clicklistener){
view view = inflater.inflate(r.layout.spiner_window_layout, null);
setcontentview(view);
setwidth(layoutparams.wrap_content);
setheight(layoutparams.wrap_content);
setfocusable(true);
colordrawable dw = new colordrawable(0x00);
setbackgrounddrawable(dw);
mlistview = (listview) view.findviewbyid(r.id.listview);
mlistview.setadapter(madapter=new myadapter());
mlistview.setonitemclicklistener(clicklistener);
private class myadapter extends baseadapter{
public int getcount() {
return list.size();
public object getitem(int position) {
return list.get(position);
public long getitemid(int position) {
return position;
public view getview(int position, view convertview, viewgroup parent) {
viewholder holder=null;
if(convertview==null){
holder=new viewholder();
convertview=inflater.inflate(r.layout.spiner_item_layout, null);
holder.tvname=(textview) convertview.findviewbyid(r.id.tv_name);
convertview.settag(holder);
}else{
holder=(viewholder) convertview.gettag();
holder.tvname.settext(getitem(position).tostring());
return convertview;
private class viewholder{
private textview tvname;
4).spiner_window_layout.xml popupwindow顯示的布局檔案 裡面就一個listview控件
<?xml version="1.0" encoding="utf-8"?>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignparentright="true"
android:orientation="vertical">
<listview
android:id="@+id/listview"
android:layout_width="fill_parent"
android:cachecolorhint="#00000000"
android:background="@drawable/shape_popupwindow_list_bg"
android:scrollbars="none" >
</listview>
還有一些其他布局,我就不一一貼出來了,有興趣的可以去看看源碼.這個demo還是比較簡單的,相信大家都能看懂.
推薦下自己建立的android qq群:202928390 歡迎大家的加入.
<a target="_blank" href="http://download.csdn.net/detail/lowprofile_coding/9240321">點選下載下傳源碼</a>