牛骨文教育服务平台(让学习变的简单)

主界面布局(知识点:GridView)

mainscreen.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:background="@color/background"
    android:orientation="vertical" >
   
    <GridView
     android:id="@+id/gv_main"  
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="10dip"
        android:verticalSpacing="20dip"
        android:numColumns="3"
        >
       
    </GridView>

</LinearLayout>

android:background="@color/background"--设置背景颜色,此处采用颜色资源文件(/mobilesafe/res/values/color.xml)

color.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="background">#ff404040</color>
    <color name="textcolor">#ffd0d0d0</color>
   
</resources> 

GridView :

android:numColumns="3"-----列数设置为3列
android:horizontalSpacing="10dip"-----两列之间的边距
android:verticalSpacing="20dip"-----两行之间的边距

数据适配MainUIAdapter(知识点:LayoutInflater,BaseAdapter )

MainUIAdapter :

package com.liuhao.mobilesafe.adapter;

import com.liuhao.mobilesafe.R;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
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 MainUIAdapter extends BaseAdapter {
	
	private static final String TAG = "MainUIAdapter";
	private Context context;//用于接收传递过来的Context对象
	private LayoutInflater inflater;
	private static ImageView iv_icon;
	private static TextView tv_name;
	private SharedPreferences sp;
	
	public MainUIAdapter(Context context) {
		this.context = context;
		inflater = LayoutInflater.from(context);
		sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
	}

	// 数据源,子条目的文本内容
	private static String[] names = { "手机防盗", "通讯卫士", "软件管理", "任务管理", "上网管理",
			"手机杀毒", "系统优化", "高级工具", "设置中心" };

	// 数据源,子条目的对应图片
	private static int[] icons = { R.drawable.widget05, R.drawable.widget02,
			R.drawable.widget01, R.drawable.widget07, R.drawable.widget05,
			R.drawable.widget04, R.drawable.widget06, R.drawable.widget03,
			R.drawable.widget08 };

	/**
	 * How many items are in the data set represented by this Adapter.
	 * 在此适配器中所代表的数据集中的条目数
	 */
	@Override
	public int getCount() {
		return names.length;
	}

	/**
	 * Get the data item associated with the specified position in the data set.
	 * 获取数据集中与指定索引对应的数据项
	 */
	@Override
	public Object getItem(int position) {
		return position;
	}

	/**
	 * Get the row id associated with the specified position in the list.
	 * 取在列表中与指定索引对应的行id
	 */
	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		//getView()方法被调用了多少次?
		//9次?
		//GridView 控件bug
		// 使用静态变量引用来减少内存中申请的引用的个数
		Log.i(TAG, "getView" + position);
		
		// 得到布局文件对应的View对象
		// inflate()方法一般接收两个参数,第一个参数就是要加载的布局id,
		// 第二个参数是指给该布局的外部再嵌套一层父布局,如果不需要就直接传null。
		View view = inflater.inflate(R.layout.mainscreen_item, null);
		iv_icon = (ImageView) view.findViewById(R.id.iv_main_icon);
		tv_name = (TextView) view.findViewById(R.id.tv_main_name);
		
		iv_icon.setImageResource(icons[position]);
		tv_name.setText(names[position]);
		if(position == 0){
			// 从SharedPreferences获取条目的文本内容
			String name = sp.getString("lost_name", null);
			if(!"".equals(name) && null != name){
				tv_name.setText(name);
			}
		}
		
		return view;
	}

}

子条目的布局:

mainscreen_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dip"
    android:layout_height="100dip"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:background="@drawable/item_background"
    >
   
    <ImageView
        android:id="@+id/iv_main_icon"
        android:layout_width="60dip"
        android:layout_height="60dip"
        android:src="@drawable/ic_launcher"
        android:scaleType="fitXY"
        />

    <TextView
        android:id="@+id/tv_main_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="@color/textcolor"
        android:text="程序功能"
        />
</LinearLayout> 

为每个条目添加背景图(知识点:android:shape)

item_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <!-- 边框 -->
    <stroke
        android:width="1dip"
        android:color="#ff202020"
        />
   
    <!-- 指定边角 -->
    <corners
        android:radius="2dip"
        />
   
    <!-- 指定固定颜色 -->
    <solid
        android:color="@color/background"
        />
   
    <!-- 渐变色 -->
    <gradient />

</shape> 

MainActivity中使用

gv_main = (GridView) this.findViewById(R.id.gv_main);
adapter = new MainUIAdapter(this);
gv_main.setAdapter(adapter);

效果:

Screenshot_2014-11-04-14-46-21

GridView中的getView()方法被调用了多少次?9次(9个条目)?

每个条目会多次调用getView()方法;

原因:

GridView的item的layout中android:layout_height定义为wrap_content , 绘制item高度时系统并不知道item应该绘制多高,它会先取一条来试探以确定item绘制的具体高度,这样就导致多调用了一次getView方法。在滑动、长按等GridView需要重绘的情况下,getView的调用次数可能会不止多一次。

解决方法1:

由于多次调用getView()方法,每次都会重新生成一个iv_icon ,tv_name控件对象,从而产生多个对象实例,造成空间浪费。因此,一个简单的优化方法就是,将二者设置为类静态变量:

private static ImageView iv_icon;
private static TextView tv_name;

使用静态变量引用来减少内存中申请的引用的个数,这样可以在一定程度上提高效率。

后续还会有其他优化方法。