1. 程式人生 > >ListView載入不同的佈局

ListView載入不同的佈局

我們平常使用ListView多半都是用來展示資料的,且每個item的模式都是一樣的。但是還有更多的時候會出現不一樣的佈局,比如你手機聯絡人的方式。好了不多說,看效果圖吧!
在這裡插入圖片描述
為什麼我會想到寫這篇文章,事情的起因是我在專案中遇到一個需求。需要實現一個WiFi列表介面,熟悉手機的盆友應該知道WiFi列表不是我們隨便寫一個ListVIew就能實現的了。開始我的想法是用線性佈局,中間夾雜需要的標題欄佈局等,可是我操作了大半天,發現一個很致命的問題,已經連線過的WiFi是不會出現在周圍熱點的列表裡面的。(因為專案的WiFi列表實現了自動重新整理)如果按照這種思路走下去,在每次重新整理之後都要一個一個對照,然後將已經連線的從列表裡面移除。很顯然這個效率太低了,於是就問同事,同事就告訴我說用一個列表啊。嗯!確實很感謝他。

後來我又開始了不斷尋找的道路。在找了很多資料以後終於找到了答案(可能是我自身能力不足,有的東西真的看不明白吧)。關鍵在於Adapter裡面的兩個方法。

 @Override
    public int getViewTypeCount() {
        return 2;
    }
    這個方法就是返回你需要展示不同的型別數量,我的專案就兩個,所以返回2.
 @Override
    public int getItemViewType(int position) {
        if (types == 0){
            if (position == 3){
                return 0;
            }else {
                return 1;
            }
        }else {
            return position % 2;
        }
    }
    這個是根據位置返回你需要展示的型別,待會我們就會用到。比如說返回0說明我想用1號佈局,
    返回1說明我想用2號佈局。特別注意一點的這裡返回的值必須從0開始,
    且不能大於你返回的型別總數(就是上一個方法返回的數值,原理是看到大神這麼說的<(* ̄▽ ̄*)/)
    當然你可以在這裡加上自己的邏輯判斷哪個位置返回什麼,我這裡只是簡單的顯示2個佈局。

好來看介面卡程式碼

public class ListAdapter extends BaseAdapter {
    private List<String> contents;
    private LayoutInflater inflater;
    //模擬判斷效果,你可以改成其他的值,當然在getItemViewType裡面的值也要變一下
    private int types = 1;
    
    public ListAdapter(List<String> contents, Context context) {
        this.contents = contents;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return contents == null ? 0 :contents.size();
    }

    @Override
    public Object getItem(int position) {
        return contents.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        int type = getItemViewType(position);
        if (view == null) {
            switch (type) {
                case 0:
                    view = inflater.inflate(R.layout.item_right, parent, false);
                    break;
                case 1:
                    view = inflater.inflate(R.layout.item_left, parent, false);
                    break;
            }
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.imageView = (ImageView) view.findViewById(R.id.image);
            holder.textView = (TextView) view.findViewById(R.id.text_content);
        }
        holder.textView.setText(contents.get(position));
        return view;
    }

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (types == 0){
            if (position == 3){
                return 0;
            }else {
                return 1;
            }
        }else {
            return position % 2;
        }
    }

    static class ViewHolder {
        TextView textView;
        ImageView imageView;
    }
}

注意這個方法

 public View getView(int position, View convertView, ViewGroup parent) {
        View view = convertView;
        int type = getItemViewType(position);
        if (view == null) {
            switch (type) {
                case 0:
                    view = inflater.inflate(R.layout.item_right, parent, false);
                    break;
                case 1:
                    view = inflater.inflate(R.layout.item_left, parent, false);
                    break;
            }
        }
        ViewHolder holder = (ViewHolder) view.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.imageView = (ImageView) view.findViewById(R.id.image);
            holder.textView = (TextView) view.findViewById(R.id.text_content);
        }
        holder.textView.setText(contents.get(position));
        return view;
    }

這裡我們根據在getItemViewType裡面返回的值進行判斷選擇不同的佈局展示。
佈局程式碼(如果你實現不了這種佈局的話我也沒辦法幫你了騷年)我就不貼了。最後貼上MainActivity程式碼

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private List<String> contents;
    private ListAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.list_content);
        contents = new ArrayList<>();
        for (int i = 1;i < 50;i++){
            contents.add("這是第 " + i + "條item");
        }

        adapter = new ListAdapter(contents,this);
        listView.setAdapter(adapter);
    }

}

怎麼樣,還是比較簡單的吧,問題還沒有結束哦。如果你設定了點選監聽事件你會發現每個item都是會響應點選事件的。如果我想讓第四個不能響應點選事件怎麼辦?這個你可以再Adapter裡面重寫這個方法

 @Override
    public boolean isEnabled(int position) {
        return super.isEnabled(position);
    }

這個你同樣根據位置來判斷就好比如說我想讓第四個不能點選那就可以寫成這樣

 public boolean isEnabled(int position) {
        if (position == 4){
        //返回false表示不可以點選
            return false;
        }else {
        //返回true表示可以點選
            return true;
        }
    }

好了,到此,已經實現了不同佈局的載入以及某個item不可點選。正所謂好事多磨,僅僅靠這個是不可能做出很好的內容的,加油吧各位!自己也要加油!