天天看點

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

1.5 動态填充布局 顯示資料 ListView

自定義 AdapterView的視圖

 在AdapterView(ListView、GridView)沒有資料時顯示自定義視圖

  • 目錄

  • 1.5.1初步認識ListView
  • 1.5.2 用ArrayAdapter實作視圖填充
  • 1.5.3 在ListView為空時顯示TextView的内容
  • 1.5.4 在ListView為空時 顯示自定義的Layout内容
  • 1.5.5 自定義ListView中的每行layout效果 

1.5.1初步認識ListView

  ListView提供的常用XML屬性如下所示:

  • android:divider:設定 List 清單項的分隔條(即可用顔色分隔,也可用 Drawable 分隔)。
  • android:dividerHeight:設定分隔條的高度。
  • android:entries:指定一個數組資源,Android 将根據該數組資源來生成 ListView。
  • android:footerDividerEnabled:如果設定為 false,則不在 footer View 之前繪制分隔條。
  • android:footerDividerEnabled:如果設定為 false,則不在 header View 之後繪制分隔條

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
 
    <!-- 直接使用數組資源給出清單項 -->
    <!-- 設定使用藍色的分隔條 -->
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/books"
        android:divider="#00f"
        android:dividerHeight="2px"
        android:headerDividersEnabled="false"/>
</LinearLayout>
           

values/目錄下建立一個arrays.xml檔案,在其中定義books數組。

<resources>
    <string-array name="books">
        <item>Hello Java</item>
        <item>Hello JavaWeb</item>
        <item>Hello Android</item>
        <item>Hello Python</item>
    </string-array>
</resources>
           

MianActivity.java

public class MainActivity extends AppCompatActivity {

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

效果: 

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

1.5.2 用ArrayAdapter實作視圖填充

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- 設定使用綠色的分隔條 -->
        <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:divider="#0f0"
            android:dividerHeight="2px"
            android:headerDividersEnabled="false"/>
    </LinearLayout>
           

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        // 擷取界面ListView元件
        ListView listView = (ListView) findViewById(R.id.listview);

        // 定義一個數組
        final String[] books = {"Hello Java", "Hello JavaWeb", "Hello Android","Hello Python"};
        // 将數組包裝成ArrayAdapter
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, books);

        // 為ListView設定Adapter
        listView.setAdapter(adapter);

       //可以為ListView綁定清單項點選事件監聽器
    }
}
           

 為ListView綁定清單項點選事件監聽器

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "點選了" + books[position],
                        Toast.LENGTH_SHORT).show();
            }
        });
           
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

1.5.3 在ListView為空時顯示TextView的内容

activty_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.listviewtest.duan.listviewtest.MainActivity">

    <TextView
        android:id="@+id/mian_empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="空空如也"
        />
    <!--ListView為空時顯示textView文字内容-->
    <ListView
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>
</FrameLayout>
           

ActivityMain.java

public class MainActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ListView list =(ListView)findViewById(R.id.myList) ;
        TextView empty=(TextView)findViewById(R.id.mian_empty);
        list.setEmptyView(empty);//ListView 為空時填充TextView
    }
}
           

效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

說明:一旦程式獲得了ListView之後,就需要為ListView設定它要顯示的清單項。

通過setAdapter(Adapter)方法為之提供Adapter,并由Adapter提供清單項。

提示:ListView、GridView、Spinner、Gallery等都隻是容器,而Adapter負責提供每個“清單項”的元件,AdapterView則負責采用合适的方式顯示這些清單項。

AbsListView提供的常用XML屬性及相關方法如下表所示: 

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

ListView提供的常用XML屬性如下表所示: 

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

接下來為ListView添加内容:

arry.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="books">
        <item>Hello Java</item>
        <item>Hello JavaWeb</item>
        <item>Hello Android</item>
        <item>Hello Python</item>
    </string-array>
</resources>
           

在activty_main.xml裡面設定填充内容

android:entries="@array/books"
           
<ListView
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/books">
    </ListView>
           

 效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

1.5.4 在ListView為空時 顯示自定義的Layout内容

在上面基礎上添加一些内容

activty_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.listviewtest.duan.listviewtest.MainActivity">
    <LinearLayout
        android:id="@+id/mian_linearlayout_empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="空空如也"
            />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="點選重新整理"/>
    </LinearLayout>


    <!--ListView為空時顯示LinearLayout内容-->
    <ListView
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
      >
    </ListView>
</FrameLayout>
           

修改:

LinearLayout empty=(LinearLayout)findViewById(R.id.mian_linearlayout_empty);
           

效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

為ListView添加内容:

<ListView
        android:id="@+id/myList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:entries="@array/books">
    </ListView>
           

效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

1.5.5 自定義ListView中的每行layout效果 

  • ArrayAdapter :将List文字内容添加到TextView
四個步驟:
  • //加載設定的ListView布局   
setContentView(R.layout.custom_item_layout);
           
  • // 定義一個List集合   
final List<String> components = new ArrayList<>();
           
  • // 将List包裝成ArrayAdapter添加到自定義的布局
       同時傳入四個參數 :  上下文,自定義行顯示的布局,TextVieW ID,List數組  
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.custom_item, R.id.content_tv, components);
           
  • // 為ListView設定Adapter 
listView.setAdapter(adapter);
           

先看一下示例代碼:

  • 自定義ListView行效果:custom_item.xml
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
<?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="horizontal"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/icon_img"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:padding="5dp"
        android:src="@mipmap/ic_launcher"/>

    <TextView
        android:id="@+id/content_tv"
        android:text="list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:textColor="@color/colorPrimaryDark"/>
</LinearLayout>
           
  • 添加一個ListView布局   cusyom_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
           

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_item_layout); //加載設定的ListView布局

        // 擷取界面ListView元件
        ListView listView = (ListView) findViewById(R.id.listview);

        // 定義一個List集合
        final List<String> components = new ArrayList<>();
        components.add("國文");
        components.add("數學");
        components.add("英語");
       

        // 将List包裝成ArrayAdapter添加到設定的布局
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                R.layout.custom_item, R.id.content_tv, components);
       //傳入四個參數:上下文,自定義行顯示的布局,TextVieW ID,List數組

        // 為ListView設定Adapter
        listView.setAdapter(adapter);

        // 為ListView清單項綁定點選事件監聽器
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                Toast.makeText(MainActivity.this, components.get(position),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
}
           

最終效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

結合 LayoutInflater 來實作效果:

LayoutInflater:它的作用類似于findViewById()。

                         不同點是LayoutInflater是用來找res/layout/下的xml布局檔案并執行個體化;

                          而findViewById()是找xml布局檔案下的具體widget控件(如Button、TextView等)。

  LayoutInflater 是一個抽象類,獲得 LayoutInflater 執行個體有以下三種方式。

  • LayoutInflaterinflater=getLayoutInflater();     // 通過Activity擷取
  • LayoutInflaterinflater=LayoutInflater.from(context);    // 通過靜态方法擷取
  • LayoutInflaterinflater= (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);    // 通過系統服務擷取

獲得執行個體後,需要通過inflater.inflater()方法來查找并執行個體化布局檔案

  • LayoutInflater inflater =this.getLayoutInflater();     // 擷取LayoutInflater對象
        View itemView = inflater.inflate(R.layout.custom_row, null);    // 執行個體化布局檔案
  • View row= LayoutInflater.from(this).inflate(R.layout.custom_row,parent,false)

custom_item    cusyom_item_layout 兩個布局檔案沿用上面的

用到的圖檔:(根據不同名稱選擇不同圖檔)

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_item_layout);

        // 擷取界面元件
        ListView listView = (ListView) findViewById(R.id.listview);

        // 定義要顯示的數組
        String[] contents = {"a+", "C+", "B+", "A+", "d+",
                "C+", "B+","D+"};

        // 将數組包裝為自定義MyArrayAdapter
        MyArrayAdapter adapter = new MyArrayAdapter(this, R.layout.custom_item, contents);

        // 為ListView設定Adapter
        listView.setAdapter(adapter);
    }
    public class MyArrayAdapter extends ArrayAdapter {
        private Activity mContext = null; // 上下文環境
        private int mResourceId; // 清單項布局資源ID
        private String[] mItems; // 清單内容數組

        public MyArrayAdapter(Activity context, int resId, String[] items){
            super(context, resId, items);
            // 儲存參數
            mContext = context;
            mResourceId = resId;
            mItems = items;
        }

        @NonNull
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 擷取LayoutInflater對象
            LayoutInflater inflater = mContext.getLayoutInflater();
            // 裝載清單項視圖
            View itemView = inflater.inflate(mResourceId, null);

            // 擷取清單項之元件
            TextView contentTv = (TextView) itemView.findViewById(R.id.content_tv);
            ImageView letterImg = (ImageView) itemView.findViewById(R.id.icon_img);

            // 取出要顯示的資料
            String content = mItems[position].trim();

            // 給TextView設定顯示值
            contentTv.setText(content);
            // 根據内容首字母判斷要顯示的圖示
            if(content.startsWith("a") || content.startsWith("A")) {
                letterImg.setImageResource(R.drawable.a);
            } else if(content.startsWith("b") || content.startsWith("B")) {
                letterImg.setImageResource(R.drawable.b);
            } else if(content.startsWith("c") || content.startsWith("C")) {
                letterImg.setImageResource(R.drawable.c);
            } else if(content.startsWith("d") || content.startsWith("D")) {
                letterImg.setImageResource(R.drawable.d);
            }

            // 傳回清單項視圖
            return itemView;
        }
    }
}
           

 看一下最終效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

在看一個例子:

先看一下要實作的效果:

自定義ListView行的顯示效果

點選時改變背景顔色

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

背景顔色是個漸變的顔色,我們可以使用shape 标簽 和 背景選擇器 selector來實作顔色漸變,同時減少背景圖檔的使用

具體關于shape标簽具體使用參考:https://blog.csdn.net/qq_36408196/article/details/82779247

shape标簽屬性:<shape   xmlns:android="http://schemas.android.com/apk/res/android"

android:shape="???">

<padding:内容與形狀邊界的内間距

<gradient: 設定形狀的漸變顔色

<corners: 設定圓角,隻适用于rectangle類型,可分别設定四個角不同半徑的圓角,當設定的圓角半徑很大時,比如200dp,就可變成弧形邊

<stroke: 設定描邊,可描成實線或虛線。

<size: 設定形狀預設的大小,可設定寬度和高 

shape="ring"時的幾個屬性
  • android:innerRadius  内環的半徑
  • android:innerRadiusRatio  浮點型,以環的寬度比率來表示内環的半徑,預設為3,表示内環半徑為環的寬度除以3,該值會被android:innerRadius覆寫
  • android:thickness  環的厚度
  • android:thicknessRatio  浮點型,以環的寬度比率來表示環的厚度,預設為9,表示環的厚度為環的寬度除以9,該值會被android:thickness覆寫
  • android:useLevel  一般為false,否則可能環形無法顯示,隻有作為LevelListDrawable使用時才設為true
Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

首先,在drawable檔案夾下建立一個背景選擇器:row_background.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
        android:drawable="@drawable/row_background_pressed"/>
    <item android:drawable="@drawable/row_background_default"/>
</selector>
           

然後,建立背景選擇器裡用到的兩個資源布局:row_background_default.xml和row_background_pressed.xml

row_background_default.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#CFCFCF"
        android:endColor="#DCDCDC"
        android:type="linear"
        android:angle="270" />
</shape>
           

row_background_pressed.xml 

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
    <gradient
        android:startColor="#EEE8CD"
        android:centerColor="#A0522D"
        android:endColor="#CDAA7D"
        android:type="linear"
        android:angle="270" />
</shape>
           

接下來,自定義ListView的行視圖:custom_row.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="10dp"
    android:background="@drawable/row_background"
    tools:context="com.listviewtest.duan.listviewrow.MainActivity">
    <ImageView
        android:id="@+id/leftimage"
        android:layout_width="32dip"
        android:layout_height="32dip" />

    <TextView
        android:id="@+id/line1"
        android:padding="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:layout_toRightOf="@+id/leftimage"
        android:layout_centerVertical="true"
        android:gravity="center_horizontal"/>
</RelativeLayout>
           

用到的圖檔資源檔案:leftimage.bng

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView

然後,MainActivity裡實作:

  • 将list添加到setContentView中
super.onCreate(savedInstanceState);
        ListView list= new ListView(this);
        setContentView(list);
           
  • 自定義Adapter傳入參數
CustomAdapter adapter=new CustomAdapter(this,R.layout.custom_row,
                R.id.line1, items);
        list.setAdapter(adapter);

//四個參數:上下文,布局資源,TextView ID,要顯示的時候數組items或者list
           
  • Adapter 繼承 ArrayAdapter<String>
private static class  CustomAdapter extends ArrayAdapter<String>{
        public CustomAdapter(Context context,int layout,int resId,String[]items){
            super(context, layout,resId,items);
        }
           
  • 在自定義Adapter主類裡重寫getView()方法 
public View getView(int postion, View convertView, ViewGroup parent){
            View row=convertView;
            if(row==null){
                row= LayoutInflater.from(getContext()).inflate(R.layout.custom_row,parent,false);
            }
            String item =getItem(postion);
            ImageView left=(ImageView)row.findViewById(R.id.leftimage) ;
            left.setImageResource(R.drawable.imageleft);
            TextView textView=(TextView)row.findViewById(R.id.line1);
            textView.setText(item);
            return row;
        }
           

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ListView list= new ListView(this);
        setContentView(list);
        final String []items={"國文","數學","英語"};
        CustomAdapter adapter=new CustomAdapter(this,R.layout.custom_row,
                R.id.line1, items);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                Toast.makeText(MainActivity.this, "點選了" + items[position],
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
    private static class  CustomAdapter extends ArrayAdapter<String>{
        public CustomAdapter(Context context,int layout,int resId,String[]items){
            super(context, layout,resId,items);
        }

        public View getView(int postion, View convertView, ViewGroup parent){
            View row=convertView;
            if(row==null){
                row= LayoutInflater.from(getContext()).inflate(R.layout.custom_row,parent,false);
            }
            String item =getItem(postion);
            ImageView left=(ImageView)row.findViewById(R.id.leftimage) ;
            left.setImageResource(R.drawable.imageleft);
            TextView textView=(TextView)row.findViewById(R.id.line1);
            textView.setText(item);
            return row;
        }
    }


}
           

 效果:

Android整理筆記——1.5 動态填充布局 顯示資料 ListView1.5 動态填充布局 顯示資料 ListView
  • 主目錄:https://blog.csdn.net/qq_36408196/article/details/82840469

  • 下一節:1.4.6 制作ListView 的節頭部

繼續閱讀