在安卓应用中,很多带有列表的界面都提供了两种显示方式,单列显示和平铺显示,比如文件管理器,其实这两种视觉效果分别是用listview和GridView来实现的。这篇文章将讨论如何正确的实现两种视图的切换效果。
对于一个界面,如果需要设计GridView和ListView两种方式来显示一个列表,可以共用一个Adapter和一个布局来实现,这样既可以避免冗余的代码,也使整个处理过程变得更加简单。
1.首先,如下所示,将GridView和ListView布局到同一个页面中;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<?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填充数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
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中。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
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标签来控制页面的显示。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/**
* 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);
}
|
对于一些软件来说,希望达到 GridView与ListView这两种方式来显示相同的内容,在内容较少时,用户可以选择九宫格(GridView)方式浏览,在内容较多时可以切换为列表浏览(ListView),那么,这种方式改如何切换呢.
我们知道,对于任意一个ui组件来说都是View的子类,而View包含一个方法View.setVisibility (),该方法可以控制View的显示或者隐藏,那么只要在button的click事件中加入对于相应View的显示/隐藏控制即可
切换为GridView时,ListView隐藏
切换为ListView时,GridView隐藏
那么,该如何布局呢 很简单,先假设只有GridView来布局,布局完成之后,在GridView之后在更上一个完全相同属性的listview就可以了.注意在activity oncreate时就需要将其中一个隐藏
布局文件如下
接着,我们就可以在button的onclick事件中通过setVisibility(View.GONE)来隐藏了
当然,为了让界面更好看
我们还可以为这两个View加上动画以girdview为例
gridview.setLayoutAnimation();
这个方法就可以为对应的view加上动画了
我这里写一个模拟3d的切换动画生成对应的layoutanimationController
通过Rotate3d这个类实现
1 2 3 4 5 6 7 8 9 | public static LayoutAnimationController getgridlayoutAnim() { LayoutAnimationController controller; Animation anim=new Rotate3dAnimation(90f,0f,0.5f,0.5f,0.5f,false); anim.setDuration(500); controller=new LayoutAnimationController(anim,0.1f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); return controller; } |
将这个layoutanimationcontroller传入后再试试
动画还是挺炫的呵呵