android提供的spinner可能會因為項目的需求而不能使用,這時候我們往往會自己定義一個。最近在做的項目遇到了這種情況,自己用popuwindow定義了一個下拉框的樣式,記錄下來留着以後參考~先上效果圖~
點選頭部右邊的按鈕,彈出長度與上方的控件長度一緻的下拉框。
下面來說說是如何實作的。定義出第一個圖檔的布局和彈出框(一個listview)的布局,程式的源碼裡面有,這裡就不在多說了~listview需要自己定義一個myspinneradapter~做好這些準備之後,就是彈出框的實作了~
檢視源代碼
<code>1</code>
<code>@override</code>
<code>2</code>
<code> </code><code>protected</code><code>void</code><code>oncreate(bundle savedinstancestate) {</code>
<code>3</code>
<code> </code><code>super</code><code>.oncreate(savedinstancestate);</code>
<code>4</code>
<code> </code><code>setcontentview(r.layout.activity_main);</code>
<code>5</code>
<code> </code><code>textview = (textview) findviewbyid(r.id.text);</code>
<code>6</code>
<code> </code><code>imgview = findviewbyid(r.id.arrowbut);</code>
<code>7</code>
<code> </code><code>// 執行個體化一個list,添加資料</code>
<code>8</code>
<code> </code><code>list =</code><code>new</code><code>arraylist<string>();</code>
<code>9</code>
<code> </code><code>list.add(</code><code>"第一展廳"</code><code>);</code>
<code>10</code>
<code> </code><code>list.add(</code><code>"第二展廳"</code><code>);</code>
<code>11</code>
<code> </code><code>list.add(</code><code>"第三展廳"</code><code>);</code>
<code>12</code>
<code> </code><code>// 執行個體化一個擴充卡,list的資料作為adapter的資料</code>
<code>13</code>
<code> </code><code>adapter =</code><code>new</code><code>myspinneradapter(</code><code>this</code><code>, list);</code>
<code>14</code>
<code> </code><code>// 預設設定下拉框的标題為資料的第一個</code>
<code>15</code>
<code> </code><code>textview.settext((charsequence) adapter.getitem(</code><code>0</code><code>));</code>
<code>16</code>
<code> </code><code>spinnerlayout = (linearlayout) findviewbyid(r.id.spinnerid);</code>
<code>17</code>
<code> </code><code>// 點選右側按鈕,彈出下拉框</code>
<code>18</code>
<code> </code><code>imgview.setonclicklistener(</code><code>new</code><code>onclicklistener() {</code>
<code>19</code>
<code>20</code>
<code> </code><code>@override</code>
<code>21</code>
<code> </code><code>public</code><code>void</code><code>onclick(view v) {</code>
<code>22</code>
<code>23</code>
<code> </code><code>showwindow(v);</code>
<code>24</code>
<code>25</code>
<code> </code><code>}</code>
<code>26</code>
<code> </code><code>});</code>
<code>27</code>
<code> </code><code>}</code>
<code>28</code>
<code>29</code>
<code> </code><code>@suppresswarnings</code><code>(</code><code>"deprecation"</code><code>)</code>
<code>30</code>
<code> </code><code>public</code><code>void</code><code>showwindow(view v) {</code>
<code>31</code>
<code> </code><code>// 找到布局檔案</code>
<code>32</code>
<code> </code><code>layout = (linearlayout) layoutinflater.from(</code><code>this</code><code>).inflate(r.layout.mypinner_dropdown,</code><code>null</code><code>);</code>
<code>33</code>
<code> </code><code>// 執行個體化listview</code>
<code>34</code>
<code> </code><code>listview = (listview) layout.findviewbyid(r.id.listview);</code>
<code>35</code>
<code> </code><code>// 設定listview的擴充卡</code>
<code>36</code>
<code> </code><code>listview.setadapter(adapter);</code>
<code>37</code>
<code> </code><code>// 執行個體化一個popuwindow對象</code>
<code>38</code>
<code> </code><code>popupwindow =</code><code>new</code><code>popupwindow(v);</code>
<code>39</code>
<code> </code><code>// 設定彈框的寬度為布局檔案的寬</code>
<code>40</code>
<code> </code><code>popupwindow.setwidth(spinnerlayout.getwidth());</code>
<code>41</code>
<code> </code><code>// 高度随着内容變化</code>
<code>42</code>
<code> </code><code>popupwindow.setheight(layoutparams.wrap_content);</code>
<code>43</code>
<code> </code><code>// 設定一個透明的背景,不然無法實作點選彈框外,彈框消失</code>
<code>44</code>
<code> </code><code>popupwindow.setbackgrounddrawable(</code><code>new</code><code>bitmapdrawable());</code>
<code>45</code>
<code> </code><code>// 設定點選彈框外部,彈框消失</code>
<code>46</code>
<code> </code><code>popupwindow.setoutsidetouchable(</code><code>true</code><code>);</code>
<code>47</code>
<code> </code><code>// 設定焦點</code>
<code>48</code>
<code> </code><code>popupwindow.setfocusable(</code><code>true</code><code>);</code>
<code>49</code>
<code> </code><code>// 設定所在布局</code>
<code>50</code>
<code> </code><code>popupwindow.setcontentview(layout);</code>
<code>51</code>
<code> </code><code>// 設定彈框出現的位置,在v的正下方橫軸偏移textview的寬度,為了對齊~縱軸不偏移</code>
<code>52</code>
<code> </code><code>popupwindow.showasdropdown(v, -textview.getwidth(),</code><code>0</code><code>);</code>
<code>53</code>
<code> </code><code>// listview的item點選事件</code>
<code>54</code>
<code> </code><code>listview.setonitemclicklistener(</code><code>new</code><code>onitemclicklistener() {</code>
<code>55</code>
<code>56</code>
<code>57</code>
<code> </code><code>public</code><code>void</code><code>onitemclick(adapterview<?> arg0, view arg1,</code><code>int</code><code>arg2,</code><code>long</code> <code>arg3) {</code>
<code>58</code>
<code> </code><code>// todo auto-generated method stub</code>
<code>59</code>
<code> </code><code>textview.settext(list.get(arg2));</code><code>// 設定所選的item作為下拉框的标題</code>
<code>60</code>
<code> </code><code>// 彈框消失</code>
<code>61</code>
<code> </code><code>popupwindow.dismiss();</code>
<code>62</code>
<code> </code><code>popupwindow =</code><code>null</code><code>;</code>
<code>63</code>
<code>64</code>
<code>65</code>
<code>66</code>
注釋已經寫得很清楚了,這裡就不再多說了~
源碼:
<code>https://github.com/liangjie0521/testspinner2.git</code>
有時候因為項目的界面風格 很多控件如果使用原生的樣式感覺會與整體風格有些不搭 是以需要自定義樣式 很多項目中自定義控件都是必不可少的 這裡參考網上的一些資料 實作了一個自定義spinner 記錄下 加深印象
效果圖:
彈框是通過一個重寫的dialog和listview實作
第一步 重寫dialog類selectdialog.java
[java]
view plaincopyprint?
import android.app.alertdialog;
import android.content.context;
import android.os.bundle;
public class selectdialog extends alertdialog {
public selectdialog(context context, int theme) {
super(context, theme);
}
public selectdialog(context context) {
super(context);
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
// setcontentview(r.layout.slt_cnt_type);
}
第二步重寫spinner類customerspinner.java
import java.util.arraylist;
import android.util.attributeset;
import android.view.layoutinflater;
import android.view.view;
import android.widget.adapterview;
import android.widget.listview;
import android.widget.spinner;
import android.widget.adapterview.onitemclicklistener;
public class customerspinner extends spinner implements onitemclicklistener {
public static selectdialog dialog = null;
private arraylist<string> list;
public static string text;
public customerspinner(context context, attributeset attrs) {
super(context, attrs);
//如果視圖定義了onclicklistener監聽器,調用此方法來執行
public boolean performclick() {
context context = getcontext();
final layoutinflater inflater = layoutinflater.from(getcontext());
final view view = inflater.inflate(r.layout.formcustomspinner, null);
final listview listview = (listview) view
.findviewbyid(r.id.formcustomspinner_list);
listviewadapter adapters = new listviewadapter(context, getlist());
listview.setadapter(adapters);
listview.setonitemclicklistener(this);
dialog = new selectdialog(context, r.style.dialog);//建立dialog并設定樣式主題
layoutparams params = new layoutparams(650, layoutparams.fill_parent);
dialog.setcanceledontouchoutside(true);// 設定點選dialog外部任意區域關閉dialog
dialog.show();
dialog.addcontentview(view, params);
return true;
public void onitemclick(adapterview<?> view, view itemview, int position,
long id) {
setselection(position);
settext(list.get(position));
if (dialog != null) {
dialog.dismiss();
dialog = null;
}
public arraylist<string> getlist() {
return list;
public void setlist(arraylist<string> list) {
this.list = list;
public string gettext() {
return text;
public void settext(string text) {
this.text = text;
這裡用listview來顯示資料 arraylist<string> list存儲所要顯示的資料 text存儲每次spinner選中的值 在監聽spinner并擷取目前選中的值的時候用到
dialog的樣式設定:styles.xml
[html]
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="dialog" parent="@android:style/theme.dialog">
<item name="android:windowframe">@null</item><!--邊框-->
<item name="android:windowisfloating">true</item><!--是否浮現在activity之上-->
<item name="android:windowistranslucent">false</item><!--半透明-->
<item name="android:windownotitle">true</item><!--無标題-->
<!-- <item name="android:windowbackground">@color/alpha_bg</item>背景透明-->
<item name="android:backgrounddimenabled">false</item><!--模糊-->
</style>
</resources>
listview的代碼很簡單 自己寫一個adapter就好了
第三步 在xml檔案中引用自定義的spinner
main.xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#ffffff" android:id="@+id/layout"
>
<textview android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="草帽海賊團 :" android:textcolor="#000000" android:textsize="20dp"
android:layout_margintop="15dp"/>
<com.spinner.test.customerspinner android:background="@drawable/bg_spinner"
android:layout_width="150dp" android:layout_height="50dp" android:id="@+id/spinner"
android:layout_margintop="15dp"/>
</linearlayout>
到這裡差不多就完成了 不過這個還有個缺陷 每次使用時通過 spinner.setlist(list);為其加載資料 當程式傳回或者退出這個節目在進入時 listview中的資料會重複 這裡隻能通過這個辦法來解決了
@override
public boolean onkeydown(int keycode, keyevent event) {
if(keycode == keyevent.keycode_back){
list.clear();
return super.onkeydown(keycode, event);
每次傳回或退出時 清空list 就可以啦
下載下傳位址:http://download.csdn.net/download/wanglj0925/4634852
spinner是常用控件之一,屬于adapterview的一種,應用時需要 通過adapter 将資料和view視圖聯系起來,并且有各種事件回調函數,較為友善。
但發現一個問題,spinner控件,很難控制其外觀與顯示大小,在同一個布局中,很難與其它控件外觀協調起來。最後用button控件模仿spinner的效果,應用起來也較為友善。
應用button時,需要圖檔配合button的各種切換狀态,點選時彈出對話框,實作清單選擇即可。
需要寫一個selector檔案,在button狀态變化時,切換背景圖,在button的onclick事件函數中,彈出選擇清單對話框
大小: 21 kb
button.rar (77.7 kb)
下載下傳次數: 542
檢視圖檔附件