ViewSwitcher实现程序列表分屏和动画效果
2013-01-25 16:00
561 查看
Android的Launcher界面功能菜单是一个列表,当应用程序较多时,可以向下滑动查看其它,如下图。那能不能将功能菜单做成横向拖动,并且分屏的效果呢?
本文对该问题进行研究,要达到的目标如下:
1、可以实现应用程序的分屏显示,当一屏放不下时,放入另一个屏。
2、屏与屏之间切换为横向。
3、屏与屏之间切换时有动画效果,一个屏退出,一个屏出现。
本文的方法暂时没有解决屏幕切换随着手的移动而逐渐切换的问题,但是本文的屏幕切换可以采用手势的方式。
分屏和横向显示不是很难解决的问题,关键问题在于动画效果的实现。由于在屏幕切换时两个屏同时发生动画,一个退出,一个进入,因此至少要同时存在两个View。实际上Android已经为我们考虑了这种情况。ViewSwitcher就是专门针对这种情况而设计的。
ViewSwitcher内部保存了两个View,通过我们的控制可以显示前一个和后一个,并且我们可以设置在切换中两个View的动画。View的生成为ViewFactory生成。该类还是比较简单的,需要详细研究参考google文档和源代码。
多的不说,上代码吧。
首先我们模拟一下功能菜单的数据部分,也就是分几个屏,每个屏有哪些应用之类的东西。注释较多,不多解释。
/**
* 该类模拟了功能菜单的数据部分
*/
public class MenuData {
/**该常量代表每一屏能够容纳的应用程序数目*/
public static final int NUMBER_IN_ONE_SCREEN = 9;
/**该类代表每个应用程序的数据部分*/
public static class DataItem {
public String dataName; //应用程序名称
public Drawable drawable; //应用程序图标
}
/**该类代表了一个屏的所有应用程序*/
public static class MenuDataOneScreen {
ArrayList<DataItem> mDataItems = new ArrayList<DataItem>();
}
/**该数据时该类的主要部分,所有屏的列表,实际上该类就是代表了所有的屏*/
ArrayList<MenuDataOneScreen> mScreens = new ArrayList<MenuDataOneScreen>();
/**对该类进行赋予数据*/
public void setMenuItems(ArrayList<DataItem> dataItems) {
int screenNum = dataItems.size() / NUMBER_IN_ONE_SCREEN;
int remain = dataItems.size() % NUMBER_IN_ONE_SCREEN;
screenNum += remain == 0 ? 0 : 1;
int pos = 0;
for (int i = 0; i < screenNum; i++) {
MenuDataOneScreen screen = new MenuDataOneScreen();
for (int j = 0; j < NUMBER_IN_ONE_SCREEN; j++) {
if (pos <= dataItems.size() - 1) {
screen.mDataItems.add(dataItems.get(pos));
pos++;
}
}
mScreens.add(screen);
}
}
/**获取屏的数目*/
public int getScreenNumber() {
return mScreens.size();
}
/**根据屏的索引,获取某个屏的数据*/
public MenuDataOneScreen getScreen(int screenIndex) {
return mScreens.get(screenIndex);
}
}
然后,我们重载ViewFactory类,定义我们如何生成View,生成什么样的View。
public class SlideViewFactory implements ViewFactory{
LayoutInflater mInflater;
public SlideViewFactory(Context context) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**这个函数就是得到我们要生成的View,这里实际上直接从布局得到,
*我们定义的是一个GridView ,一个GridView用于显示一屏的应用程序*/
public View makeView() {
return mInflater.inflate(R.layout.slidelistview, null);
}
}
从上面的代码我们可以看出,我们生成的View实际是一个GridView,GridView要想和数据关联,则需要一个Adapter,因此我们下面定义该Adapter:
public class OneScreenListAdapter extends BaseAdapter{
private MenuDataOneScreen mScreen;
private LayoutInflater mInflater;
public OneScreenListAdapter(Context context) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**这里将数据赋予Adapter*/
public void setScreenData(MenuDataOneScreen screenData) {
mScreen = screenData;
}
public int getCount() {
return mScreen.mDataItems.size();
}
public Object getItem(int position) {
return mScreen.mDataItems.get(position);
}
public long getItemId(int position) {
return position;
}
/**该函数中将数据和View进行关联*/
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = mInflater.inflate(R.layout.labelicon, null);
}
ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
TextView textView = (TextView) view.findViewById(R.id.textview);
imageView.setImageDrawable(mScreen.mDataItems.get(position).drawable);
textView.setText(mScreen.mDataItems.get(position).dataName);
return view;
}
}
下面是继承ViewSwitcher的部分,用来实现两个屏的切换。
/**该部分是ViewSwitcher的重载,用该类实现两个屏的切换和切换的动画实现*/
public class SlideMenuSwitcher extends ViewSwitcher{
private MenuData mMenuData;
private int mCurrentScreen;
private Context mContext;
public SlideMenuSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
setFactory(new SlideViewFactory(context));
// setAnimateFirstView(false);
mContext = context;
}
/**通过该方法将数据赋值进去,并且将初始的屏显示出来*/
public void setData(ArrayList<DataItem> dataItems) {
mMenuData = new MenuData();
mMenuData.setMenuItems(dataItems);
mCurrentScreen = mMenuData.getScreenNumber() / 2;
GridView listView = (GridView) getCurrentView();
OneScreenListAdapter adapter = new OneScreenListAdapter(mContext);
adapter.setScreenData(mMenuData.getScreen(mCurrentScreen));
listView.setAdapter(adapter);
}
/**该方法用于显示下一屏*/
public void showNextScreen() {
if (mCurrentScreen < mMenuData.getScreenNumber() - 1) {
mCurrentScreen++;
setInAnimation(mContext, R.anim.slide_in_right);
setOutAnimation(mContext, R.anim.slide_out_left);
} else {
return;
}
setViewData(mCurrentScreen);
showNext();
}
/**该方法用于显示上一屏*/
public void showPreviousScreen() {
if (mCurrentScreen > 0) {
mCurrentScreen--;
setInAnimation(mContext, R.anim.slide_in_left);
setOutAnimation(mContext, R.anim.slide_out_right);
} else {
return;
}
setViewData(mCurrentScreen);
showPrevious();
}
private void setViewData(int index) {
GridView listView = (GridView) getNextView();
OneScreenListAdapter adapter = new OneScreenListAdapter(mContext);
adapter.setScreenData(mMenuData.getScreen(index));
listView.setAdapter(adapter);
}
}
我们将在一个Activity中,将我们做好的东西实现。首先在布局中将我们写的SlideMenuSwitcher。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.winuxxan.SlideMenu.SlideMenuSwitcher
android:id="@+id/slide_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<Button
android:id="@+id/button_prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="<--"
/>
<Button
android:id="@+id/button_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="-->"
/>
</RelativeLayout>
最后,实现我们的Activity:
public class SlideMenuActivity extends Activity {
/** Called when the activity is first created. */
SlideMenuSwitcher switcher;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
switcher = (SlideMenuSwitcher) findViewById(R.id.slide_view);
switcher.setData(makeItems()); //将24个应用程序赋值到swithcer中。
findViewById(R.id.button_next).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
switcher.showNextScreen(); //点击右边按钮,显示下一屏,当然可以采用手势
}
});
findViewById(R.id.button_prev).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
switcher.showPreviousScreen(); //点击左边按钮,显示上一屏,当然可以采用手势
}
});
}
/**模拟24个应用程序*/
private ArrayList<DataItem> makeItems() {
ArrayList<DataItem> items = new ArrayList<DataItem>();
for (int i = 0; i < 24; i++) {
String label = "" + i;
Drawable drawable = getResources().getDrawable(R.drawable.icon);
DataItem item = new DataItem();
item.dataName = label;
item.drawable = drawable;
items.add(item);
}
return items;
}
}
本文对该问题进行研究,要达到的目标如下:
1、可以实现应用程序的分屏显示,当一屏放不下时,放入另一个屏。
2、屏与屏之间切换为横向。
3、屏与屏之间切换时有动画效果,一个屏退出,一个屏出现。
本文的方法暂时没有解决屏幕切换随着手的移动而逐渐切换的问题,但是本文的屏幕切换可以采用手势的方式。
分屏和横向显示不是很难解决的问题,关键问题在于动画效果的实现。由于在屏幕切换时两个屏同时发生动画,一个退出,一个进入,因此至少要同时存在两个View。实际上Android已经为我们考虑了这种情况。ViewSwitcher就是专门针对这种情况而设计的。
ViewSwitcher内部保存了两个View,通过我们的控制可以显示前一个和后一个,并且我们可以设置在切换中两个View的动画。View的生成为ViewFactory生成。该类还是比较简单的,需要详细研究参考google文档和源代码。
多的不说,上代码吧。
首先我们模拟一下功能菜单的数据部分,也就是分几个屏,每个屏有哪些应用之类的东西。注释较多,不多解释。
/**
* 该类模拟了功能菜单的数据部分
*/
public class MenuData {
/**该常量代表每一屏能够容纳的应用程序数目*/
public static final int NUMBER_IN_ONE_SCREEN = 9;
/**该类代表每个应用程序的数据部分*/
public static class DataItem {
public String dataName; //应用程序名称
public Drawable drawable; //应用程序图标
}
/**该类代表了一个屏的所有应用程序*/
public static class MenuDataOneScreen {
ArrayList<DataItem> mDataItems = new ArrayList<DataItem>();
}
/**该数据时该类的主要部分,所有屏的列表,实际上该类就是代表了所有的屏*/
ArrayList<MenuDataOneScreen> mScreens = new ArrayList<MenuDataOneScreen>();
/**对该类进行赋予数据*/
public void setMenuItems(ArrayList<DataItem> dataItems) {
int screenNum = dataItems.size() / NUMBER_IN_ONE_SCREEN;
int remain = dataItems.size() % NUMBER_IN_ONE_SCREEN;
screenNum += remain == 0 ? 0 : 1;
int pos = 0;
for (int i = 0; i < screenNum; i++) {
MenuDataOneScreen screen = new MenuDataOneScreen();
for (int j = 0; j < NUMBER_IN_ONE_SCREEN; j++) {
if (pos <= dataItems.size() - 1) {
screen.mDataItems.add(dataItems.get(pos));
pos++;
}
}
mScreens.add(screen);
}
}
/**获取屏的数目*/
public int getScreenNumber() {
return mScreens.size();
}
/**根据屏的索引,获取某个屏的数据*/
public MenuDataOneScreen getScreen(int screenIndex) {
return mScreens.get(screenIndex);
}
}
然后,我们重载ViewFactory类,定义我们如何生成View,生成什么样的View。
public class SlideViewFactory implements ViewFactory{
LayoutInflater mInflater;
public SlideViewFactory(Context context) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**这个函数就是得到我们要生成的View,这里实际上直接从布局得到,
*我们定义的是一个GridView ,一个GridView用于显示一屏的应用程序*/
public View makeView() {
return mInflater.inflate(R.layout.slidelistview, null);
}
}
从上面的代码我们可以看出,我们生成的View实际是一个GridView,GridView要想和数据关联,则需要一个Adapter,因此我们下面定义该Adapter:
public class OneScreenListAdapter extends BaseAdapter{
private MenuDataOneScreen mScreen;
private LayoutInflater mInflater;
public OneScreenListAdapter(Context context) {
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**这里将数据赋予Adapter*/
public void setScreenData(MenuDataOneScreen screenData) {
mScreen = screenData;
}
public int getCount() {
return mScreen.mDataItems.size();
}
public Object getItem(int position) {
return mScreen.mDataItems.get(position);
}
public long getItemId(int position) {
return position;
}
/**该函数中将数据和View进行关联*/
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null) {
view = mInflater.inflate(R.layout.labelicon, null);
}
ImageView imageView = (ImageView) view.findViewById(R.id.imageview);
TextView textView = (TextView) view.findViewById(R.id.textview);
imageView.setImageDrawable(mScreen.mDataItems.get(position).drawable);
textView.setText(mScreen.mDataItems.get(position).dataName);
return view;
}
}
下面是继承ViewSwitcher的部分,用来实现两个屏的切换。
/**该部分是ViewSwitcher的重载,用该类实现两个屏的切换和切换的动画实现*/
public class SlideMenuSwitcher extends ViewSwitcher{
private MenuData mMenuData;
private int mCurrentScreen;
private Context mContext;
public SlideMenuSwitcher(Context context, AttributeSet attrs) {
super(context, attrs);
setFactory(new SlideViewFactory(context));
// setAnimateFirstView(false);
mContext = context;
}
/**通过该方法将数据赋值进去,并且将初始的屏显示出来*/
public void setData(ArrayList<DataItem> dataItems) {
mMenuData = new MenuData();
mMenuData.setMenuItems(dataItems);
mCurrentScreen = mMenuData.getScreenNumber() / 2;
GridView listView = (GridView) getCurrentView();
OneScreenListAdapter adapter = new OneScreenListAdapter(mContext);
adapter.setScreenData(mMenuData.getScreen(mCurrentScreen));
listView.setAdapter(adapter);
}
/**该方法用于显示下一屏*/
public void showNextScreen() {
if (mCurrentScreen < mMenuData.getScreenNumber() - 1) {
mCurrentScreen++;
setInAnimation(mContext, R.anim.slide_in_right);
setOutAnimation(mContext, R.anim.slide_out_left);
} else {
return;
}
setViewData(mCurrentScreen);
showNext();
}
/**该方法用于显示上一屏*/
public void showPreviousScreen() {
if (mCurrentScreen > 0) {
mCurrentScreen--;
setInAnimation(mContext, R.anim.slide_in_left);
setOutAnimation(mContext, R.anim.slide_out_right);
} else {
return;
}
setViewData(mCurrentScreen);
showPrevious();
}
private void setViewData(int index) {
GridView listView = (GridView) getNextView();
OneScreenListAdapter adapter = new OneScreenListAdapter(mContext);
adapter.setScreenData(mMenuData.getScreen(index));
listView.setAdapter(adapter);
}
}
我们将在一个Activity中,将我们做好的东西实现。首先在布局中将我们写的SlideMenuSwitcher。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.winuxxan.SlideMenu.SlideMenuSwitcher
android:id="@+id/slide_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<Button
android:id="@+id/button_prev"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="<--"
/>
<Button
android:id="@+id/button_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="-->"
/>
</RelativeLayout>
最后,实现我们的Activity:
public class SlideMenuActivity extends Activity {
/** Called when the activity is first created. */
SlideMenuSwitcher switcher;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
switcher = (SlideMenuSwitcher) findViewById(R.id.slide_view);
switcher.setData(makeItems()); //将24个应用程序赋值到swithcer中。
findViewById(R.id.button_next).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
switcher.showNextScreen(); //点击右边按钮,显示下一屏,当然可以采用手势
}
});
findViewById(R.id.button_prev).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
switcher.showPreviousScreen(); //点击左边按钮,显示上一屏,当然可以采用手势
}
});
}
/**模拟24个应用程序*/
private ArrayList<DataItem> makeItems() {
ArrayList<DataItem> items = new ArrayList<DataItem>();
for (int i = 0; i < 24; i++) {
String label = "" + i;
Drawable drawable = getResources().getDrawable(R.drawable.icon);
DataItem item = new DataItem();
item.dataName = label;
item.drawable = drawable;
items.add(item);
}
return items;
}
}
相关文章推荐
- ViewSwitcher实现程序列表分屏和动画效果 推荐
- android ViewSwitcher实现程序列表分屏和动画效果(仿Launcher)
- ViewSwitcher实现程序列表分屏和动画效果
- ViewSwitcher实现程序列表分屏和动画效果
- ViewSwitcher实现程序列表分屏和动画效果
- android仿系统Launcher界面,实现分屏,左右滑动效果(ViewSwitcher)
- Android RecyclerView (二)初学,实现GridView列表和瀑布流效果。
- Android插值器、动画、分解详解,实现View摆动效果
- [Android]ScaleViewPager--仿“想去”客户端图片展示效果--中轴旋转ViewPager动画实现
- 利用ViewFlipper实现View间的动画效果(平移/渐变...)
- 安卓之在SurfaceView中实现动画效果
- Android RecyclerView实现数据列表展示效果
- ViewPaper实现滑屏切换页面及动画效果(仿优酷客户端)
- Android实现带动画效果的自定义View
- IOS开动画效果之──实现 pushViewController 默认动画效果
- Android入门(34)——第十一章 使用ViewFlipper实现屏幕切换动画效果
- Android自定义View 实现水波纹动画引导效果
- Android自定义View之实现流行的新浪微博底部菜单:高仿“咸鱼APP”的底部菜单动画效果。
- viewpager实现进入程序之前的欢迎界面效果
- Android成长日记-使用ViewFlipper实现屏幕切换动画效果