Android 适配器教程 (六)
我们的适配器学习已经接近尾声了。尽管这不是一个大问题,可是确实是值得学习的一块知识,回忆一下之前五讲的知识。我们已经学到了非常多东西了。
在之前五讲中。我们已经由浅入深的认识了适配器,从最简单的ListView写起,最后完毕了自己定义适配器的简单样例,然后又为大家解说了ViewHolder和settag在自己定义适配器中的应用,帮助大家理解了getView方法。还解说了关于ListView性能方面的优化问题。
自己定义适配器这一部分是我们这次学习真正的重点,非常多问题能够用安卓原生适配器进行解决,可是也有非常多问题必须通过自己定义适配器才干合适的解决。
在第四讲我已经提到过了,关于自己定义适配器,我们将有两个样例,一个简单一点,一个略微难一点。今天我们这个样例,也是最后一个样例是一个比較繁琐的项目,希望大家认真学习,并从中领悟到知识,真正学通安卓适配器。
好的。先介绍一下今天要做的样例。大家都知道Listview和GridView,这两个都是安卓开发中经常使用的控件。今天我们要把他们两个结合在一起,使用listView嵌套GridView,形成一种能够存放多张图片的UI设计。Google+androidclient就是这个样子,是不是感到有一点小繁琐,只是没事,我会一步步的依照写代码的思路解说的。
说明一下。我还是会在之前几讲的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 style="font-size:18px;"><? 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 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相关教程请訪问:\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();
} }
activity_main.xml:
<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:
Android 适配器教程 (六)的更多相关文章
- [转]Android Studio系列教程六--Gradle多渠道打包
转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...
- Android Studio系列教程六--Gradle多渠道打包
Android Studio系列教程六--Gradle多渠道打包 2015 年 01 月 15 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzh ...
- Android精通教程V
前言 大家好,给大家带来Android精通教程V的概述,希望你们喜欢 前言 如果你想学习Android开发,那你就要了解Java编程,这是基础,也是重点,如果没学Java语法就先学习,再来学Andro ...
- CRL快速开发框架系列教程六(分布式缓存解决方案)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- Android扫盲教程大全经典教程全分享
Android扫盲教程大全经典教程全分享,相当于android的简单用户手册下载路径 Android扫盲教程大全经典教程全分享.rar
- Android 游戏教程让人物动起来
在这里给大家分享Android游戏教程怎样让人物动起来,话不多说了,直接进入正题. 一. 准备工作 首先要准备好要使用的人物动作图和地形图.把它分割成16个不同的动作,循环播放同一行的4个不同 ...
- Mac下载安装Android Studio教程
今天把公司闲置的一台Mac-mini重装了下系统感觉用着速度还不错,平时上班用的机器USB有些问题,所以打算用这台Mac.以往开发用Intellij Idea就够用,但是这次项目引用的jar包太多,遭 ...
- C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- Android studio教程
Android studio教程: http://jingyan.baidu.com/season/44062
随机推荐
- zabbix2.4升级到2.5 --考虑升级到zabbix3.0
现在zabbix服务器,zabbix服务日志频繁出现MySQL server has gone away,经搜索,此问题在zabbix2.5之前是zabbix的一个bug,zabbix2.5后已经修 ...
- 九度oj 题目1007:奥运排序问题
九度oj 题目1007:奥运排序问题 恢复 题目描述: 按要求,给国家进行排名. 输入: 有多组数据. 第一行给出国家数N,要求排名的国家数M,国家号 ...
- 树状数组--前n项和;
树状数组是和线段树类似的数据结构,基本上树状数组可以做的线段树都可以做: 树状数组就是一个数组,在信息记录上有一些特点,以动态求前n项和为例:可以改变数组的某一个元素,求前n项和: 数组tree[ i ...
- HDU——1418抱歉(平面欧拉公式)
抱歉 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- [CODEVS1912] 汽车加油行驶问题(分层图最短路)
传送门 吐槽:神tm网络流 dis[i][j][k] 表示到 (i, j) 还有 k 油的最优解 然后跑spfa,中间分一大堆情况讨论 1.当前队头还有油 1.目标点有加油站——直接过去 2.目标点每 ...
- ubuntu下卸载python2和升级python3.5
卸载python只需一条语句就可以实现 sudu apt-get remove python ubuntu下安装python3 sudo apt-get install python3 但这样只安装了 ...
- scrapy之spiders
官方文档:https://docs.scrapy.org/en/latest/topics/spiders.html# 一句话总结:spider是定义爬取的动作(是否跟进新的链接)及分析网页结构(提取 ...
- 3D标签
动态实现3D标签, 主要代码: // // XLMatrix.h // XLSphereView // // Created by 史晶晶 on 16/4/4. // Copyright © 2016 ...
- Wmap5 测试80端口 Your port 80 is actually used by :Server: Microsoft-HTTPAPI/2.0
问题:win7系统! 在wamp5的apache启动不了: 目录下点击[测试80端口]的时候提示:Your port 80 is actually used by : Server: Microsof ...
- Linux内核解析:进程间通信:管道
管道的定义管道的用途管道的操作管道非法read与write内核实现解析管道通信原理及其亲戚通信解析父子进程通信解析亲缘关系的进程管道通信解析管道的注意事项及其性质管道有以下三条性质shell管道的实现 ...