閱讀661 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android 適配器教程 (六)

我們的適配器學習已經接近尾聲了,雖然這不是一個大問題,但是確實是值得學習的一塊知識,回想一下之前五講的知識,我們已經學到了很多東西了。

              

在之前五講中,我們已經由淺入深的認識了適配器,從最簡單的ListView寫起,最後完成了自定義適配器的簡單例子,然後又為大家講解了ViewHolder和settag在自定義適配器中的應用,幫助大家理解了getView方法,還講解了關於ListView性能方麵的優化問題。自定義適配器這一部分是我們這次學習真正的重點,很多問題可以用安卓原生適配器進行解決,但是也有很多問題必須通過自定義適配器才能合適的解決。

 

在第四講我已經提到過了,關於自定義適配器,我們將有兩個例子,一個簡單一點,一個稍微難一點,今天我們這個例子,也是最後一個例子是一個比較繁瑣的項目,希望大家認真學習,並從中領悟到知識,真正學通安卓適配器。

 

好的,先介紹一下今天要做的例子,大家都知道Listview和GridView,這兩個都是安卓開發中常用的控件,今天我們要把他們兩個結合在一起,使用listView嵌套GridView,形成一種可以存放多張圖片的UI設計,Google+android客戶端就是這個樣子是不是感到有一點小繁瑣,不過沒事,我會一步步的按照寫代碼的思路講解的。

 

說明一下,我還是會在之前幾講的Demo上繼續添加,這次寫完我就把源碼雙手奉上了哦,看過前幾篇的讀者就比較熟悉了。

 

好的,現在開始動手寫吧:

 

項目開始:

 

(1)也還是先在activity_main.xml裏添加一個button,一會跳轉的時候使用。

(2)然後新建一個類FinalDemo繼承自Activity作為我們第四個個例子的Activity@Override我們的onCreate方法。

(3)新建一個xml文件finaldemo.xml作為我們的布局文件,其中也是包含一個文本域和一個ListView

代碼如下:

finaldemo.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
    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="這是ListView與GridView嵌套的一個例子" >
    </TextView>

    <ListView
        android:
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

(4)然後需要定義好一個用來顯示每一個列內容的xml文件Listitem3.xmlListitem3.xml 包含橫向的一個圖片還有一個GridviewGridview的橫向滾動的實現布局主要是把gridview嵌套在HorizontalScrollView裏麵GridView的一些屬性還要在java代碼中實現,一會大家看源碼就明白了。

Listitem3.xml

代碼如下:

<span ><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <ImageView
        android:
        android:layout_width="150px"
        android:layout_height="150px"
        android:scaleType="fitXY"
        />

    <HorizontalScrollView
        android:
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:scrollbars="none" >

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

            <GridView
                android:
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@null" >
            </GridView>
        </LinearLayout>
    </HorizontalScrollView>

</LinearLayout></span>


再嵌套一個線性布局是為了在Java代碼中控製橫向Gridview長度(總長度)的,通過LayoutParams方法。


(5)然後需要定義好一個用來顯示橫向GridView每一個內容的gridview_item.xml,內容是一個ImageView和一個textview


代碼如下:

gridview_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

(6)然後是寫出GridView的適配器這裏在第四講講已經很詳細的說過了,我就不再多費口舌了,有什麼問題還請大家再回去看看吧:

新建一個類GridViewAdapter extends BaseAdapter,之後重寫方法就Ok了~


以下是該類的完整代碼:

package com.example.adapterdemo;

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

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

import android.widget.ImageView;
import android.widget.TextView;

public class GridViewAdapter extends BaseAdapter {

	private LayoutInflater mInflater;
	private List<Map<String, Object>> Griddata;

	// 構造器,接收數據
	public GridViewAdapter(Context context, List<Map<String, Object>> Griddata) {

		this.mInflater = LayoutInflater.from(context);
		this.Griddata = Griddata;
	}

	@Override
	public int getCount() {

		return Griddata == null ? 0 : Griddata.size();
	}

	@Override
	public Object getItem(int position) {

		return Griddata.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) {

			holder = new ViewHolder();

			convertView = mInflater.inflate(R.layout.gridview_item, null);
			holder.Gridimg = (ImageView) convertView.findViewById(R.id.Grid_iv);
			holder.Gridtext = (TextView) convertView.findViewById(R.id.Grid_tv);

			convertView.setTag(holder);

		} else {

			holder = (ViewHolder) convertView.getTag();
		}

		holder.Gridimg.setBackgroundResource((Integer) Griddata.get(position)
				.get("Gridimg"));
		holder.Gridtext
				.setText((String) Griddata.get(position).get("Gridtext"));

		return convertView;
	}

	public final class ViewHolder {
		public ImageView Gridimg;
		public TextView Gridtext;

	}

}

(7)然後是寫出LIstView的適配器這裏在第四講講已經很詳細的說過了,我同樣也是就不再多費口舌了,有什麼問題還請大家再回去看看吧:

新建一個類FinalDemoListAdapter extends BaseAdapter,之後重寫方法就Ok了~

其中需要注意的就有 1.構造器部分需要分兩部分得到ListView和GridView的數據。


2.原來加載數據的部分,由於我們裏麵還嵌套了一層ListView,所以除了加載了一張 圖片,還需要加載一個GridView,並且把外部獲得的給GridView的數據傳給下一層。


3.GridView的布局設置,這裏我就不多說了,有問題的話穀歌一下就明白了。


另外我這麼寫思路比較清楚,但是效率就不敢保證了,還希望大家多多指教。


下麵給出源碼:


package com.example.adapterdemo;

import java.util.List;
import java.util.Map;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;


public class FinalDemoListAdapter extends BaseAdapter {
	
	 //列寬

    private int cWidth = 120;

    //水平間距

    private int hSpacing = 10;


	private LayoutInflater mInflater;
	private List<Map<String, Object>> Listdata;
	private List<Map<String, Object>> Griddata;
	private Context context;

	// 構造器,接收數據
	public FinalDemoListAdapter(Context context,
			List<Map<String, Object>> Listdata,
			List<Map<String, Object>> Griddata) {
		this.context = context;
		this.mInflater = LayoutInflater.from(context);
		this.Listdata = Listdata;
		this.Griddata = Griddata;
	}

	@Override
	public int getCount() {

		return Listdata == null ? 0 : Listdata.size();
	}

	@Override
	public Object getItem(int position) {

		return Listdata.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) {

			holder = new ViewHolder();

			convertView = mInflater.inflate(R.layout.listitem3, null);

			holder.Listimg = (ImageView) convertView.findViewById(R.id.list_iv);
			holder.gridview = (GridView) convertView
					.findViewById(R.id.gridview);

			convertView.setTag(holder);

		} else {

			holder = (ViewHolder) convertView.getTag();
		}

		// 加載數據
		holder.Listimg.setBackgroundResource((Integer) Listdata.get(position)
				.get("Listimg"));

		// 加載Gridview
		GridViewAdapter ga = new GridViewAdapter(context, Griddata);

		int i = ga.getCount();

		LayoutParams params = new LayoutParams(i * (115 + 10),

		LayoutParams.WRAP_CONTENT);

		holder.gridview.setLayoutParams(params);

		holder.gridview.setColumnWidth(cWidth);

		holder.gridview.setHorizontalSpacing(hSpacing);

		holder.gridview.setStretchMode(GridView.NO_STRETCH);

		holder.gridview.setNumColumns(i);

		holder.gridview.setAdapter(ga);

		return convertView;
	}

	public final class ViewHolder {
		public ImageView Listimg;
		public GridView gridview;

	}

}

(8)之後我們再回到FinalDem之前那樣增加適配器,添加數據就好了:


我從網上下了點頭像。。。後麵的安卓機器人圖片是示例。


下麵是源碼:

package com.example.adapterdemo;

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

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class FinalDemo extends Activity {
	private ListView lv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.finaldemo);
		lv = (ListView) findViewById(R.id.finaldemolistview);
		FinalDemoListAdapter myadapter = new FinalDemoListAdapter(this,
				getListData(), getGridData());
		lv.setAdapter(myadapter);
	}

	private List<Map<String, Object>> getListData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head1);
		
		list.add(map);

		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head2);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head4);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head5);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head6);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head7);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head8);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head9);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head10);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head11);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head12);
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Listimg", R.drawable.head13);
		list.add(map);
		
		return list;
		
	}

	private List<Map<String, Object>> getGridData() {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 1");
		
		list.add(map);

		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 2");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 3");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 4");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 5");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 6");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 7");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 8");
		
		list.add(map);
		
		map = new HashMap<String, Object>();
		map.put("Gridimg", R.drawable.ic_launcher);
		map.put("Gridtext", "info 9");
		
		list.add(map);
		return list;
	}
}


到此為止就搞定了!,讓我們再看一下實現效果




為了能看出效果,我把橫向的Gridview拉動了一下,所以是對不齊的,這裏我橫向的部分設置的底色為透明,如果在加一張背景圖片的話,相信效果會不錯的,這隻是一個Demo,在調整一下間距和尺寸,我想效果會好很多,嗬嗬~


這樣我們的教程就算是徹底結束了,希望大家能從中學到些東西就好了,這樣我的Demo程序也一並寫完了,源碼地址我會附在文章的最後~

差點忘了我還沒給大家activity_main.xml和MainActivity的源碼,這裏也再貼一下吧:


MainActivity:

package com.example.adapterdemo;



import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	private Button bt_1;
	private Button bt_2;
	private Button bt_3;
	private Button bt_4;
	private Button bt_5;
	private Button bt_6;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_1=(Button)findViewById(R.id.button1);
        bt_2=(Button)findViewById(R.id.button2);
        bt_3=(Button)findViewById(R.id.button3);
        bt_4=(Button)findViewById(R.id.button4);
        bt_5=(Button)findViewById(R.id.button5);
        bt_6=(Button)findViewById(R.id.button6);
        
        bt_1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,ArrayAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,SimpleCursorAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_3.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,SimpleAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_4.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,MyAdapterDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_5.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				Intent dataIntent = new Intent(MainActivity.this,FinalDemo.class);
				 startActivity(dataIntent);
			}
		});
        
        bt_6.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				aboutWarn();
			}
		});
    }

    private void aboutWarn(){
		AlertDialog.Builder builder = new Builder(this); 
		builder.setMessage("這是關於學習適配器的一個例子\n作者MingChao Sun\n相關教程請訪問:\nhttps://blog.csdn.net/sunmc1204953974");
		builder.setTitle("關於");
		builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				dialog.dismiss();
			}
		});
		builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				dialog.dismiss();
			}
		});
		builder.create().show();
	}

   
}


activity_main.xml:


<RelativeLayout xmlns:andro
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button1"
         android:layout_marginTop="27dp"
         android:text="SimpleCursorAdapterDemo" />

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button4"
         android:layout_marginTop="26dp"
         android:text="ListView與GridView嵌套的Demo" />

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:text="關於" />

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignLeft="@+id/button2"
         android:layout_below="@+id/button6"
         android:layout_marginTop="20dp"
         android:text="ArrayAdapterDemo" />

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_below="@+id/button2"
         android:layout_marginTop="18dp"
         android:text="SimpleAdapterDemo" />

     <Button
         android:
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_below="@+id/button3"
         android:layout_marginTop="25dp"
         android:text="MyAdapterDemo" />
     
</RelativeLayout>


好了,這就算是徹底結束了,希望大家有所所收獲!


我也是學生,水平有限,還請大家多多指教!


另外請大家尊重原創,轉載請付上我文章的地址哦~謝謝~


源碼的地址:

(一個實例徹底學會適配器)AdapterDemo.zip:

https://download.csdn.net/detail/sunmc1204953974/7689411


最後更新:2017-04-03 05:39:35

  上一篇:go 使用係統自帶windows圖片查看器打開圖片
  下一篇:go 判斷單鏈是否循環,並且找出第一個循環節點