天天看點

Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  

android提供的spinner可能會因為項目的需求而不能使用,這時候我們往往會自己定義一個。最近在做的項目遇到了這種情況,自己用popuwindow定義了一個下拉框的樣式,記錄下來留着以後參考~先上效果圖~

Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  

點選頭部右邊的按鈕,彈出長度與上方的控件長度一緻的下拉框。

Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  

下面來說說是如何實作的。定義出第一個圖檔的布局和彈出框(一個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&lt;string&gt;();</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&lt;?&gt; 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  記錄下 加深印象

效果圖:

Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  
Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義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&lt;string&gt; 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&lt;?&gt; view, view itemview, int position,  

            long id) {  

        setselection(position);  

        settext(list.get(position));  

        if (dialog != null) {  

            dialog.dismiss();  

            dialog = null;  

        }  

    public arraylist&lt;string&gt; getlist() {  

        return list;  

    public void setlist(arraylist&lt;string&gt; list) {  

        this.list = list;  

    public string gettext() {  

        return text;  

    public void settext(string text) {  

        this.text = text;  

這裡用listview來顯示資料 arraylist&lt;string&gt; list存儲所要顯示的資料 text存儲每次spinner選中的值 在監聽spinner并擷取目前選中的值的時候用到

dialog的樣式設定:styles.xml

[html]

&lt;?xml version="1.0" encoding="utf-8"?&gt;  

&lt;resources&gt;  

    &lt;style name="dialog" parent="@android:style/theme.dialog"&gt;  

        &lt;item name="android:windowframe"&gt;@null&lt;/item&gt;&lt;!--邊框--&gt;  

        &lt;item name="android:windowisfloating"&gt;true&lt;/item&gt;&lt;!--是否浮現在activity之上--&gt;  

        &lt;item name="android:windowistranslucent"&gt;false&lt;/item&gt;&lt;!--半透明--&gt;  

        &lt;item name="android:windownotitle"&gt;true&lt;/item&gt;&lt;!--無标題--&gt;  

       &lt;!-- &lt;item name="android:windowbackground"&gt;@color/alpha_bg&lt;/item&gt;背景透明--&gt;  

        &lt;item name="android:backgrounddimenabled"&gt;false&lt;/item&gt;&lt;!--模糊--&gt;  

    &lt;/style&gt;  

&lt;/resources&gt;  

listview的代碼很簡單 自己寫一個adapter就好了

第三步 在xml檔案中引用自定義的spinner

main.xml

&lt;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"  

     &gt;  

    &lt;textview android:layout_width="wrap_content" android:layout_height="wrap_content"  

        android:text="草帽海賊團 :" android:textcolor="#000000" android:textsize="20dp"  

        android:layout_margintop="15dp"/&gt;  

    &lt;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"/&gt;  

&lt;/linearlayout&gt;  

到這裡差不多就完成了 不過這個還有個缺陷 每次使用時通過 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事件函數中,彈出選擇清單對話框

Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  
Android UI自定義Spinner下拉框(用popuwindow實作)Android 實作自定義Spinner  

大小: 21 kb

button.rar (77.7 kb)

下載下傳次數: 542

檢視圖檔附件

繼續閱讀