Android惯用控件之Fragment仿Android4.0设置界面(二)

Android常用控件之Fragment仿Android4.0设置界面(二)

    在之前的基础上添加自定义的BaseAdapter,丰富显示的内容,使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法

Android惯用控件之Fragment仿Android4.0设置界面(二)

其中getView()方法最重要。

当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回3,那么只显示3行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果getCount()返回100行,那么getView是不是马上就绘制100行呢?当然不是,getView()只会绘制当前界面能显示出来的行数。下面是效果图

Android惯用控件之Fragment仿Android4.0设置界面(二)

    首先定义一个类存放要显示的数据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;

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
	}
}
在主Activity中

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>


样例代码

点击打开链接