安卓開發-ListView學習(一)

最近了解了LIstView的用法,在聽了孫老師的課程後,終於對Adapter有了一定的理解,特作此文記之。


ListView在App當中應用相當廣泛,比如QQ好友列表、微博等等,都是某種特定的列表,所以這也是一個基本的組件,是我等小白不可不跨的檻。

要完成一個ListView的設計,主要需要以下部件:

  • main.xml
  • item.xml
  • Adapter
  • 數據
    其中,main.xml包含ListView整體組件,item.xml則是ListView中每一項的具體佈局,Adapter則是將視圖中組件與數據綁定的橋樑。

首先,當然要設計好界面,我這裏設計了一個類似微博的界面。

一、layout/main.xml

在main佈局文件內,僅一個簡單的ListView組件

    <ListView
        android:id="@+id/lv_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:dividerHeight="5dp"/>

二、layout/item.xml

然後在item文件內寫了醜陋的單條微博界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <RelativeLayout
        android:layout_margin="3dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/iv_avatar"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/avatar1"
            android:layout_alignParentLeft="true"
            />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="50dp"
            android:layout_marginStart="5dp"
            android:orientation="vertical"
            android:layout_toEndOf="@+id/iv_avatar">

            <TextView
                android:id="@+id/tv_nickname"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:text="黑冰"/>

            <TextView
                android:id="@+id/tv_news_source"
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:text="來自 weibo.com"/>

        </LinearLayout>

        <Button
            android:id="@+id/btn_follow"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:text="+ 關注"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"/>

    </RelativeLayout>

    <TextView
        android:id="@+id/tv_body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="3dp"
        android:textSize="15sp"
        android:text="特朗普動用特權建牆?
California, N.Y. and other states sue Trump over national emergency to fund border wall"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_forward"
            android:layout_marginHorizontal="5dp"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="轉發3000"/>

        <Button
            android:id="@+id/btn_comment"
            android:layout_marginHorizontal="5dp"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="評論1000"/>

        <Button
            android:id="@+id/btn_love"
            android:layout_marginHorizontal="5dp"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_weight="1"
            android:text="贊1000"/>
    </LinearLayout>
</LinearLayout>

效果如下,請勿吐槽:


三、/MyAdapter.java

下一步,就是編寫自定義Adapter(因爲ArrayAdapter和SimpleAdapter比較簡單,不再贅述)

package com.example.administrator.bloglistview;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;
import java.util.Map;

public class MyAdapter extends BaseAdapter {

    List<Map<String, Object>> list;
    LayoutInflater inflater;

    public MyAdapter(Context context){
        this.inflater = LayoutInflater.from(context);
    }

    public void setList(List<Map<String, Object>> list) {
        this.list = list;
    }

    @Override
    public int getCount() {
        return list.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;

        if(convertView == null) {
            convertView = inflater.inflate(R.layout.item, null);
            holder = new ViewHolder();
            holder.avatar = convertView.findViewById(R.id.iv_avatar);
            holder.nickname = convertView.findViewById(R.id.tv_nickname);
            holder.newsSource = convertView.findViewById(R.id.tv_news_source);
            holder.follow = convertView.findViewById(R.id.btn_follow);
            holder.body = convertView.findViewById(R.id.tv_body);
            holder.forward = convertView.findViewById(R.id.btn_forward);
            holder.comment = convertView.findViewById(R.id.btn_comment);
            holder.love = convertView.findViewById(R.id.btn_love);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Map map = list.get(position);
        holder.avatar.setImageResource((Integer) map.get("avatar"));
        holder.nickname.setText((String)map.get("nickname"));
        holder.newsSource.setText((String)map.get("newsSource"));
        holder.body.setText((String)map.get("body"));

        return convertView;
    }

    public static class ViewHolder {
        ImageView avatar;
        TextView nickname;
        TextView newsSource;
        Button follow;
        TextView body;
        Button forward;
        Button comment;
        Button love;
    }
}

這裏要注意兩點:一是inflater,二是數據綁定。

首先,inflater要在構造函數裏定義好,再去getView方法裏調用inflate靜態方法,以將xml視圖轉化爲View對象。

對於數據綁定,我們用的是自定義類ViewHolder來控制。首先是將視圖裏所有組件與ViewHolder類裏的屬性綁定,再取數據賦值。

可以看出,在MyAdapter類裏,最重要的就是getView方法,因爲它完成了佈局與數據的連接。

四、/MainActivity.java

最後,在Main文件裏傳入數據,並設置好適配器即可。

package com.example.administrator.bloglistview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView lvMain = findViewById(R.id.lv_main);
        List<Map<String, Object>> list = new ArrayList<>();

        Map<String, Object> map = new HashMap<>();
        map.put("avatar", R.drawable.avatar1);
        map.put("nickname", "基篤山伯爵");
        map.put("newsSource", "來自 iPhone客戶端");
        map.put("body", "【“凱奇萊案”卷宗丟失等問題調查結果公佈:系王林清故意所爲】今天,中央政法委牽頭,中央紀委國家監委、最高檢、公安部參加的聯合調查組,公佈了最高人民法院二審審理的陝西榆林“凱奇萊案”卷宗丟失等問題的調查結果。經查明:最高法民一庭助理審判員王林清因工作中對單位產生不滿,於2016年11月25");
        list.add(map);

        map = new HashMap<>();
        map.put("avatar", R.drawable.avatar2);
        map.put("nickname", "趙麗穎穎生活軋機");
        map.put("newsSource", "來自 iPhone客戶端");
        map.put("body", "#爲了不上學做過的事#\n孫子:爺爺,我不想上學。\n爺爺:不,大孫子,你必須想!");
        list.add(map);

        map = new HashMap<>();
        map.put("avatar", R.drawable.avatar3);
        map.put("nickname", "羊咩咩愛羊");
        map.put("newsSource", "來自 榮耀8青春版 顏值擔當");
        map.put("body", "看上去很溫柔的人,不一定都是好脾氣,不生氣不代表沒脾氣,不計較不代表脾氣好,只是自己的修養剋制了心中的怒火。如果你非要觸及我的底線,我可以告訴你,我並非善良。 \u200B\u200B\u200B \u200B\u200B\u200B\u200B");
        list.add(map);

        map = new HashMap<>();
        map.put("avatar", R.drawable.avatar4);
        map.put("nickname", "英國報姐");
        map.put("newsSource", "來自 iPhone客戶端");
        map.put("body", "再來品一下歐洲老醋王格林德沃的這句“Do you think Dumbledore will mourn for you”有多陰陽怪氣[酸]本來以爲預告裏已經是醋意大發了,沒想到正片裏是一字一句頓出來的簡直酸到爆!德普自己都說格林德沃就是嫉妒紐特,你們校園黃昏戀能不能放過學長!!");
        list.add(map);

        map = new HashMap<>();
        map.put("avatar", R.drawable.avatar5);
        map.put("nickname", "Mr_張教主");
        map.put("newsSource", "來自 iPhone客戶端");
        map.put("body", "人生如夢,歲月無情。驀然回首,才發現人活着是一種心情。窮也好,富也好,得也好,失也好。一切都是過眼雲煙。不論昨天、今天、明天,能豁然開朗就是美好的一天。不論親情、友情、愛情,能永遠珍惜就是好心情。 \u200B\u200B\u200B\u200B");
        list.add(map);

        MyAdapter adapter = new MyAdapter(this);
        adapter.setList(list);
        lvMain.setAdapter(adapter);
    }
}

運行後,界面如下:


以上只是手動的寫入了一些數據,現實情況肯定要從數據庫中取,不會這麼蠢的,不必糾結。

且目前所有按鈕都是空的,下節再實現按鈕功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章