1. 程式人生 > >Android開發技巧——自定義單選或多選的ListView

Android開發技巧——自定義單選或多選的ListView

這篇其實應該是屬於寫自定義單選或多選的ListView的基礎教程,無奈目前許多人對此的實現大多都繞了遠路,反而使得這正規的寫法倒顯得有些技巧性了。

本文原創,轉載請註明在CSDN上的出處:

http://blog.csdn.net/maosidiaoxian/article/details/45867927

Android中,ListView可以設定choiceMode,可見Android對ListView的單選或多選是有進行封裝的,然而我看到的許多單選或多選的ListView,包括我以前寫的例子,以前幾個老外封裝的庫,都是自己維護了一個集合,用於存放每個item的選中狀態。這樣一來,不但程式碼顯得繁複,邏輯上也成冗餘,而且容易出BUG。

其實,ListView中,已經自己維護了一個SparseBooleanArray,用於儲存每一項的選中狀態。而對於每一項,它是通過adapter的getView中獲取的view,來設定它的選中狀態的。所以,我們需要使得adapter中,getView中返回的這個view實現Checkable介面。下面,將介紹具體實現。

這裡介紹的實現方式有兩個,一種是從零寫一個單選的ListView。另一種是呼叫我的一個庫的程式碼來實現。因為我已經對相關的必要邏輯都封裝在了兩個類裡,使得易於使用。

原生實現

1,先寫item的佈局檔案。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content">
    <RadioButton
        android:id="@+id/checkedView"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="wrap_content"
        android:layout_height="48dp" />
    <TextView
        android:id="@+id/text"
        android:gravity="center_vertical"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="48dp" />

</RelativeLayout>
注意,這裡的RadioButton,需要設定三個屬性,分別是:
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
2,接下來,繼承某個Layout,來實現可以單選的這個item。
package com.githang.android.choicelistview;

import android.content.Context;
import android.view.View;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.RadioButton;
import android.widget.TextView;

/**
 * FIXME
 *
 * @author Geek_Soledad (
[email protected]
) */ public class ChoiceView extends FrameLayout implements Checkable{ private TextView mTextView; private RadioButton mRadioButton; public ChoiceView(Context context) { super(context); View.inflate(context, R.layout.item_single_choice, this); mTextView = (TextView) findViewById(R.id.text); mRadioButton = (RadioButton) findViewById(R.id.checkedView); } public void setText(String text) { mTextView.setText(text); } @Override public void setChecked(boolean checked) { mRadioButton.setChecked(checked); } @Override public boolean isChecked() { return mRadioButton.isChecked(); } @Override public void toggle() { mRadioButton.toggle(); } }

最後,在listview的adapter的getView方法裡,返回這個實現了Checkable介面的ChoiceView。
package com.githang.android.choicelistview;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

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


public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List<String> data = new ArrayList<>();
        for(int i = 0; i < 5; i++) {
            data.add("test" + i);
        }
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        ListAdapter adapter = new ArrayAdapter<String>(this, R.layout.item_single_choice, data) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                final ChoiceView view;
                if(convertView == null) {
                    view = new ChoiceView(MainActivity.this);
                } else {
                    view = (ChoiceView)convertView;
                }
                view.setText(getItem(position));
                return view;
            }
        };
        listView.setAdapter(adapter);
    }

}

程式碼很簡單方便,完全不用自己去維護一個選中狀態的集合。Demo 專案下載地址:http://www.400gb.com/file/94898213

使用AndroidSnippet裡的類實現

接下來還有更簡單的實現方法,即使用我封裝的類來實現。這種情況下,只需要寫一個item的佈局檔案,然後寫一個adapter即可,和寫普通的ListView沒多大區別。 item 的佈局檔案:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content">
    <RadioButton
        android:id="@+id/checkedView"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="48dp" />
    <TextView
        android:id="@+id/text"
        android:gravity="center_vertical"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="48dp" />

</RelativeLayout>

關於RadioButton的三個屬性我已經在程式碼裡封裝好了,所以這裡寫不寫那三個屬性都無所謂。 接下來,就是使用我封裝的ChoiceListAdapter,來實現單選(或多選)的ListView,程式碼如下:
        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        ChoiceListAdapter adapter = new ChoiceListAdapter<String>(this, R.layout.item_single_choice,
                data, R.id.checkedView) {
            @Override
            protected void holdView(ChoiceLayout view) {
                view.hold(R.id.text);
            }

            @Override
            protected void bindData(ChoiceLayout view, int position, String data) {
                TextView text = view.get(R.id.text);
                text.setText(data);
            }
        };
        listView.setAdapter(adapter);

這裡的ChoiceLayout 我還對holder進行了封裝,用起來是不是更簡潔方便? 關於AndroidSnippet 庫,我已把程式碼託管到github :https://github.com/msdx/AndroidSnippet。其中關於單選列表的例子,在app module中有。 最後附上實現效果。 效果GIF圖:

相關推薦

Android開發技巧——定義ListView

這篇其實應該是屬於寫自定義單選或多選的ListView的基礎教程,無奈目前許多人對此的實現大多都繞了遠路,反而使得這正規的寫法倒顯得有些技巧性了。 本文原創,轉載請註明在CSDN上的出處: http://blog.csdn.net/maosidiaoxian/article

android開發定義組合控制元件

內容介紹 本文記錄,自定義組合控制元件,為了可以程式碼複用,減少程式碼量 配置控制元件屬性檔案 開啟res/values/目錄下的arss.xml檔案,新增下面屬性程式碼,如果沒有建立arrs.xml檔案。 <?xml version="1.0" enc

Android 開發定義控制元件開發-01

最近一直在忙於公司的專案,因為要去現場測試正式使用,專案不大但是經手了三個人,到我這裡只能去填坑了,不說這個了,說一下今天得主題,自定義控制元件之基本圖形繪製。 我們平時畫圖需要兩種工具:紙和筆。在Android中 Paint 就是畫筆,而Canvas類就是紙,在這裡叫做畫布。 所以

Android開發定義帶EditText的AlertDialog

接到一個需求,點選某個按鈕需要彈出一個帶有EditText的AlertDialog彈窗,實現起來並不難,簡單記錄下方便以後使用。 國際慣例,效果圖走起: 下面是實現步驟 1.首先畫自定義的佈局,我們給裡面放了四個TextView、一個EditText。 dialo

Android開發定義表情併發送出去之經典的傳送表情

本文例項講述了Android程式設計開發實現輸入(自定義表情包)QQ表情影象併發送出去別人收到並解析出來的方法。分享給大家供大家參考,原來QQ微信等傳送表情其實發送的都不是表情,而是一個富文字,收到訊息後再解析得來的,具體效果如下 : 表情傳送出去是這樣:   最近在

Android 開發定義控制元件開發-02

1.畫筆的基本設定 : 1.setColor() 該函式的作用是設定畫筆顏色,完整的函式宣告如下: void setColor(int color) 我們知道,一種顏色是由紅、綠、藍三色合成出來的,所以引數 color 只能取8位的0xAARRGGBB樣式顏色值。 其中:

Android開發筆記: 定義RadioButton樣式

1 先看效果圖 2 準備圖片   注意圖片不要太大,我的是30x30的 3 匯入圖片資源    將cb_normal.png和cb_selected.png放入drawable裡 4 建立

Android開發定義檢視

很多時候,Android自身提供給我們的檢視可能不能滿足我們的需求,這個時候我們就需要 自定義檢視 。 雖然自定義檢視很多,但總體歸為兩個類別: 簡單檢視 。簡單檢視內部當然也可以很複雜,之所以稱之為簡單檢視是因為,簡單檢視中不包括子檢視。簡單檢視幾乎總是用來處理定製繪製。

Android 開發 pickerview 定義選擇器

超好用的類:在專案直接寫入,可以自定義選擇器, package com.bestgo.callshow.custom_control; import android.content.Context; import android.content.res.TypedArra

Android開發定義可清空內容的EditText

在開發過程中不可避免的總會遇到比如登入註冊、使用者資訊修改等,這時候又是不可避免的會用到EditText控制元件。這個控制元件的使用頻率雖然幾乎類似我們吃飯用“筷子”的頻率,but能不能用出花樣

Android開發定義控制元件--ViewPager

package com.itheima18.viewpager; import java.util.ArrayList; import java.util.Timer; import java.util.concurrent.Executors; import java.util.concurrent.Sc

Android開發定義圓角矩形圖片ImageView

android中的ImageView只能顯示矩形的圖片,這樣一來不能滿足我們其他的需求,比如要顯示圓角矩形的圖片,這個時候,我們就需要自定義ImageView了,其原理就是首先獲取到圖片的Bitmap,然後進行裁剪對應的圓角矩形的bitmap,然後在onDraw()進行繪製

android開發定義屬性、View和使用

“自定義”這三字聽起來就像是一個高階程式設計師所擁有的一樣!太不接地氣了!come on,baby,讓我們成為高階程式設計師吧!哈哈! 第一步:首先建立一個工程專案,在專案中的res/values/下建立atts.xml檔案,在該檔案中: <?xml version

Android開發定義控制元件(一)---onMeasure詳解

         話說一個有十年的程式設計經驗的老漢,決定改行書法,在一個熱火炎炎的中午,老漢拿著毛筆,在一張白紙上寫了個“Hello World!”,從此開啟了他的書法旅程。那麼問題來了請問自定義一個控制元件需要怎樣的流程?我們經常說自定義控制元件,那麼究竟怎樣去自定義一

Android開發:建立定義檢視–建立一個View類

翻自:http://developer.android.com/training/custom-views/create-view.html 設計良好的定製檢視與其他精心設計的類相似。它用一種易於使用的介面封裝了一些特殊的方法集合,它高效使用記憶體和CPU等等。除了良好的設計以外,一個定製檢視應該: 符合

Android開發定義屬性的使用

自定義屬性一般會在我們自定義一個view的時候會用到,這個其實在系統應用中相當的常見,比如我目前維護的系統launcher應用,裡面就是相當多的自定義view會用到這個自定義屬性設定,那麼現將其總結總結。有些東西不去總結下來,時間久了真的會忘記。 步驟一:

android開發定義TextView設定字間距以及通過TextView控制元件屬性設定行間距

眾所周知,我們的TextView控制元件是沒有設定字間距的屬性滴!為了現實這一夢想,我玩起來了自定義TextView,從而來設定字間距: 自定義TextView設定字間距 第一步:建立自定義TextView: package com.zanel

Android開發定義介面的Dialog,並且實現按鈕的監聽回撥

該專案適合想實現自定義dialog,有懶得折騰的人。 在安卓開發的時候,往往會碰到一些特別漂亮的dialog,比如這個圖片的: 很多這種型別的dialog,介面千變萬化,於是我建立了一個通用自定義dialog,可以實現以下功能: 1、介面的自定義,全部自己用xml定義介

ionic3定義

sel images ges ima blog scrip ionic cli item import { Component } from [email protected]/* *//core‘; import { NavController } fro

CSS學習筆記三:定義框,復框,開關

sla checked 移動 transform 第一個 16px 位移 block back 一點一點學習CCS,這次學習了如何自定義單選框,復選框以及開關。 一、單選框 1、先寫好body裏面的樣式,先寫幾個框 1 <body> 2 <d