zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android 适配器教程 (六)

Android教程 适配器
2023-09-14 08:56:49 时间

我们的适配器学习已经接近尾声了,虽然这不是一个大问题,但是确实是值得学习的一块知识,回想一下之前五讲的知识,我们已经学到了很多东西了。

              

在之前五讲中,我们已经由浅入深的认识了适配器,从最简单的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:android="http://schemas.android.com/apk/res/android"

 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:id="@+id/finaldemolistview"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content" 

 /ListView 

 /LinearLayout 


(4)然后需要定义好一个用来显示每一个列内容的xml文件Listitem3.xml,Listitem3.xml 包含横向的一个图片还有一个Gridview,Gridview的横向滚动的实现布局主要是把gridview嵌套在HorizontalScrollView里面,GridView的一些属性还要在java代码中实现,一会大家看源码就明白了。

Listitem3.xml:

代码如下:

 span ?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" 

 ImageView

 android:id="@+id/list_iv"

 android:layout_width="150px"

 android:layout_height="150px"

 android:scaleType="fitXY"

 HorizontalScrollView

 android:id="@+id/app_grid"

 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:id="@+id/gridview"

 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:android="http://schemas.android.com/apk/res/android"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:orientation="vertical" 

 ImageView

 android:id="@+id/Grid_iv"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content" / 

 TextView

 android:id="@+id/Grid_tv"

 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 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;


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相关教程请访问:\nhttp://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();
 RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

 xmlns:tools="http://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:id="@+id/button2"

 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:id="@+id/button5"

 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:id="@+id/button6"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:layout_alignParentLeft="true"

 android:layout_alignParentTop="true"

 android:text="关于" / 

 Button

 android:id="@+id/button1"

 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:id="@+id/button3"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:layout_below="@+id/button2"

 android:layout_marginTop="18dp"

 android:text="SimpleAdapterDemo" / 

 Button

 android:id="@+id/button4"

 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: http://download.csdn.net/detail/sunmc1204953974/7689411



Android性能:经典ListView适配器convertView缓存及复用机制 Android中的ListView常用Adapter中都会涉及到convertView的使用,使用convertView主要是为了缓存试图View,用以增加ListView的item view加载效率。
?xml version= 1.0 encoding= utf-8 ? RelativeLayout xmlns:android= http://schemas.android.com/apk/res/android android:o