android列表视图切换:GridView和ListView两种方式来显示一个列表

在安卓应用中,很多带有列表的界面都提供了两种显示方式,单列显示和平铺显示,比如文件管理器,其实这两种视觉效果分别是用listview和GridView来实现的。这篇文章将讨论如何正确的实现两种视图的切换效果。

对于一个界面,如果需要设计GridView和ListView两种方式来显示一个列表,可以共用一个Adapter和一个布局来实现,这样既可以避免冗余的代码,也使整个处理过程变得更加简单。

1.首先,如下所示,将GridView和ListView布局到同一个页面中;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout      xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical">         
     <TextView
         android:id="@+id/app_title"
         android:layout_width="fill_parent"
         android:layout_height="44dip"
         android:text="@string/main_service_title"
         android:gravity ="center"
         android:textSize="27px"
         android:textColor="#ffffff"
         android:background ="@drawable/title_bar"/>
     <GridView
        android:id="@+id/app_grid"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:padding="10dp"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:numColumns="4"
        android:columnWidth="60dp"
        android:stretchMode="columnWidth"      
        android:gravity="center"/>
     <ListView
android:id="@+id/app_list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:divider="@drawable/divider"/>
</LinearLayout>

2.使用同一个adapter填充数据:

public class ServiceZoneAdapter extends BaseAdapter
{
    /**
     * Get view from xml layout.
     */
    private LayoutInflater    mInflater     = null;
    /**
     * A list to encapsulate servcie information.
     */
    private List<ServiceBean> mServiceBeans = null;
    public ServiceZoneAdapter(Context c, List<ServiceBean> serviceBeans)
    {
        mServiceBeans = serviceBeans;
        mInflater = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
    /**
     * Get list's size.
     *
     * @return the size of list.
     */
    public int getCount()
    {
        return mServiceBeans == null ? 0 : mServiceBeans.size();
    }
    /**
     * Get item.
     *
     * @param position
     * @return the item according to the position.
     */
    public Object getItem(int position)
    {
        return mServiceBeans == null ? null : mServiceBeans.get(position);
    }
    /**
     * Get id.
     *
     * @param position
     * @return the item's id according to the position.
     */
    public long getItemId(int position)
    {
        return position;
    }
    /**
     * Get item's view.
     *
     * @return the item view according to the position.
     */
    public View getView(int position, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            if (ServiceZone.isGridView)
            {
                convertView = mInflater.inflate(R.layout.each_app_grid_layout, parent, false);
            }
            else
            {
                convertView = mInflater.inflate(R.layout.each_app_list_layout, parent, false);
            }
        }
        ServiceBean service = (ServiceBean)getItem(position);
        if (service == null)
        {
            return convertView;
        }
        ImageView imageView = (ImageView)convertView.findViewById(R.id.app_icon);
        TextView text = (TextView)convertView.findViewById(R.id.app_name);
        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.setImageResource(service.getIconId());
        text.setText(service.getName());
        return convertView;
    }
}

3.其次,在acticity中获取相应的对象,同时设定一个标签,用于标记当前是需要用GridView或ListView中哪种方式显示;然后将数据填充到相应的View中。代码如下:

public static Boolean     isGridView                     = true;
       /**
     * Update the layout.
     */
    private void updateLayout()
    {
        if (isGridView)
        {
            if (mGridView == null)
            {
                mGridView = (GridView)findViewById(R.id.app_grid);
            }
            mGridView.setVisibility(View.VISIBLE);
            mGridView.setAdapter(new ServiceZoneAdapter(ServiceZone.this, mService));
            mGridView.setOnItemClickListener(this);
            mListView.setVisibility(View.GONE);
            if (mSelectionPosition < 0)
            {
                mSelectionPosition = 0;
            }
            mGridView.setSelection(mSelectionPosition);
        }
        else
        {
            if (mListView == null)
            {
                mListView = (ListView)findViewById(R.id.app_list);
            }
            mListView.setVisibility(View.VISIBLE);
            mListView.setAdapter(new ServiceZoneAdapter(ServiceZone.this, mService));
            mListView.setOnItemClickListener(this);
            mGridView.setVisibility(View.GONE);        
            if (mSelectionPosition < 0)
            {
                mSelectionPosition = 0;
            }
            mListView.setSelection(mSelectionPosition);
        }
}

4.通过控制isGridView标签来控制页面的显示。

/**
 * Update ui to be the selected style.
 */
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    if (item.getItemId() == R.id.menu_change)
    {
        isGridView = !isGridView;
        updateLayout();
    }
    return super.onOptionsItemSelected(item);
}