在之前的基础上添加自定义的BaseAdapter,丰富显示的内容,使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法
其中getView()方法最重要。
当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回3,那么只显示3行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果getCount()返回100行,那么getView是不是马上就绘制100行呢?当然不是,getView()只会绘制当前界面能显示出来的行数。下面是效果图
首先定义一个类存放要显示的数据Data.java
package com.example.fragmentlistdemo;
public final class Data {
// 标题
public static final String[] TITLES = { "声音", "显示", "存储", "电池", "应用程序",
"帐户与同步", "位置服务", "语言和输入法", "备份和重置", "日期与时间" };
// 详细内容
public static final String[] DETAIL = { "显示声音模式", "显示亮度、壁纸、休眠、自动旋转屏幕、字体大小",
"显示机器上SD卡的大小,总容量大小", "显示当前电量", "显示当前安装的应用程序", "显示帐号信息与同步信息",
"显示Google的位置服务、GPS", "显示当前语言信息", "显示备份的数据", "显示当前时间与日期" };
}
ListviewAdapter类继承BaseAdapter
package com.example.fragmentlistdemo;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ListviewAdapter extends BaseAdapter {
// 定义一个布局泵,它的作用类似于findViewById(),不同点是LayoutInflater是用来找layout下xml布局文件,并且实例化
private LayoutInflater inflater = null;
private ArrayList<String> items = null;
private ArrayList<Bitmap> icons = null;
//用来保存选中的item
private int selectedPosition = -1;
public void setSelectedPosition(int position) {
selectedPosition = position;
}
/**
* 构造函数
* @param context
* @param arraylist 显示的文本
* @param iconRes 显示的图标
*/
public ListviewAdapter(Context context, ArrayList<String> arraylist,
int[] iconRes) {
// TODO Auto-generated constructor stub
// LayoutInflater用来加载界面
inflater = LayoutInflater.from(context);
// 保存适配器中的每项的文字信息
this.items = arraylist;
// 获得资源中的图片作为要显示的图标
Resources res = context.getResources();
this.icons = new ArrayList<Bitmap>();
// 为每个item分配一个icon
for (int i = 0; i < iconRes.length; i++) {
Bitmap icon = BitmapFactory.decodeResource(res, iconRes[i]);
this.icons.add(icon);
}
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return items.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return items.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
// 保存每项中的控件的引用
class ViewHolder {
TextView text;
ImageView icon;
LinearLayout layout;
}
@Override
public View getView(int position, View convert, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
//第一次加载
if (convert == null) {
// 调用LayoutInflater的inflate方法加载layout文件夹中的界面
convert = inflater.inflate(R.layout.list_row, null);
holder = new ViewHolder();
holder.text = (TextView) convert.findViewById(R.id.text);
holder.icon = (ImageView) convert.findViewById(R.id.icon);
holder.layout = (LinearLayout) convert.findViewById(R.id.layout);
// 保存包含当前项控件的对象
convert.setTag(holder);
System.out.println("getView-----convert == null");
} else {
// 获取包含当前项控件的对象
holder = (ViewHolder) convert.getTag();
System.out.println("getView-----convert != null");
}
System.out.println("getView-----position = " + position);
// 设置当前项的图标和内容
holder.icon.setImageBitmap(icons.get(position));
holder.text.setText(items.get(position));
// 设置选中效果
if (selectedPosition == position) {
holder.text.setTextColor(Color.BLUE);
holder.layout.setBackgroundColor(Color.YELLOW);
} else {
holder.text.setTextColor(Color.GRAY);
holder.layout.setBackgroundColor(Color.TRANSPARENT);
}
return convert;
}
}
左边显示标题部分是一个ListFragment,在创建时把需要显示的资源传给Adapter
package com.example.fragmentlistdemo;
import java.util.ArrayList;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
public class TitleFragment extends ListFragment {
//标题的图标资源
public static final int[] ICONS = { R.drawable.icon1, R.drawable.icon2,
R.drawable.icon3, R.drawable.icon4, R.drawable.icon5,
R.drawable.icon6, R.drawable.icon7, R.drawable.icon8,
R.drawable.icon9, R.drawable.icon10 };
private ListviewAdapter listAdapter;
@Override
// 初始化TitleFragment
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < Data.TITLES.length; i++)
list.add(Data.TITLES[i]);
listAdapter = new ListviewAdapter(getActivity(), list, ICONS);
// 设置title适配器
setListAdapter(listAdapter);
// 设置选择模式
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listAdapter.setSelectedPosition(0); //进入默认是第一项
// 初始在右边frame显示详细内容
DetailsFragment df = DetailsFragment.newInstance(0); //获取DetailsFragment实例
FragmentTransaction ft = getFragmentManager().beginTransaction();// 开始一个事务
ft.replace(R.id.frameLayout, df);// 将FrameLayout的内容替换成DetailsFragment
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
//点击时显示对应的详细内容
@Override
public void onListItemClick(ListView l, View v, int index, long id) {
listAdapter.setSelectedPosition(index);
DetailsFragment df = DetailsFragment.newInstance(index);
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frameLayout, df);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
右边是根据左边选中项来显示内容
package com.example.fragmentlistdemo;在主Activity中
import android.app.Fragment;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;
public class DetailsFragment extends Fragment {
// 方法newInstance用于新建一个DetailFragment
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();
Bundle bundle = new Bundle();
bundle.putInt("index", index);
// 给Fragment初始化参数
f.setArguments(bundle);
return f;
}
// 产生显示内容的View
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView text = new TextView(getActivity());
ScrollView scroller = new ScrollView(getActivity());
scroller.addView(text);
// 设置TextView边框大小
int padding = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 4, getActivity().getResources()
.getDisplayMetrics());
text.setPadding(padding, padding, padding, padding);
text.setTextSize(25); //设置字体大小
text.setGravity(Gravity.CENTER); //设置字体颜色
text.setText(Data.DETAIL[getArguments().getInt("index")]);// 获取新建DetailFragment时声明的参数
return scroller;// 返回一个ScrollView
}
}
package com.example.fragmentlistdemo;
import android.os.Bundle;
import android.app.Activity;
/**
* 仿Android4.0的设置界面左边列表,右边详细信息;左边的列表带图标
* @author Administrator
*
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(R.style.mytheme1);
setContentView(R.layout.main);
}
}
main.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="fill_parent"
android:baselineAligned="false"
android:orientation="horizontal">
<fragment
android:id="@+id/titles"
class="com.example.fragmentlistdemo.TitleFragment"
android:layout_weight="1"
android:layout_width="250dip"
android:layout_height="match_parent" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_weight="5"
android:layout_gravity="left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/detailsElementBackground" />
</LinearLayout>
theme.xml的定义显示文件的样式
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mytheme1" >
<item name="android:textColor">#000</item>
<item name="android:textSize">20sp</item>
</style>
</resources>