ViewSwitcher常用于两个视图带动画效果的切换,如果试图里面只是图片也可以使用ImageSwitcher,前面有介绍,本文模拟手机上屏幕菜单,将应用分屏显示和切换的功能,并实现滑屏动画,部分内容来源网络,这里将其完善和优化:
SlideMenuActivity:
package com.home.testviewswitcher; import java.util.ArrayList; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import com.home.testviewswitcher.MenuData.DataItem; public class SlideMenuActivity extends Activity implements OnGestureListener { private SlideMenuSwitcher switcher; private GestureDetector detecter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); switcher = new SlideMenuSwitcher(this); setContentView(switcher); detecter = new GestureDetector(this, this); switcher.setData(makeItems()); } /** * 添加初始应用程序 * * @return */ private ArrayList<DataItem> makeItems() { ArrayList<DataItem> items = new ArrayList<DataItem>(); for (int i = 1; i < 54; i++) { String label = "App" + i; Drawable drawable = getResources().getDrawable( R.drawable.ic_launcher); DataItem item = new DataItem(); item.dataName = label; item.drawable = drawable; items.add(item); } return items; } @Override public boolean onTouchEvent(MotionEvent event) { return detecter.onTouchEvent(event); } @Override public boolean onDown(MotionEvent arg0) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float arg2, float arg3) { float instance = e1.getX() - e2.getX(); if (instance > 10) { switcher.showNextScreen(); } else if (instance < 10) { switcher.showPreviousScreen(); } return false; } @Override public void onLongPress(MotionEvent arg0) { } @Override public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) { return false; } @Override public void onShowPress(MotionEvent arg0) { } @Override public boolean onSingleTapUp(MotionEvent arg0) { return false; } @Override public boolean dispatchTouchEvent(MotionEvent ev) { detecter.onTouchEvent(ev); return super.dispatchTouchEvent(ev); } }
SlideMenuSwitcher:
package com.home.testviewswitcher; import java.util.ArrayList; import android.content.Context; import android.view.View; import android.widget.GridView; import android.widget.ViewSwitcher; import com.home.testviewswitcher.MenuData.DataItem; /** * 自定义ViewSwitcher,实现分屏和切换 * * @author Administrator * */ public class SlideMenuSwitcher extends ViewSwitcher { private MenuData mMenuData; private int mCurrentScreen;// 当前屏索引 private Context mContext; public SlideMenuSwitcher(Context context) { super(context); mContext = context; setFactory(new SlideViewFactory()); } /** * 设置数据,并将初屏显示出来 * * @param dataItems */ 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.push_left_in); setOutAnimation(mContext, R.anim.push_left_out); } else { return; } setViewData(mCurrentScreen); showNext(); } /** * 显示上一屏 */ public void showPreviousScreen() { if (mCurrentScreen > 0) { mCurrentScreen--; setInAnimation(mContext, R.anim.push_right_in); setOutAnimation(mContext, R.anim.push_right_out); } else { return; } setViewData(mCurrentScreen); showPrevious(); } /** * 为GridView设置数据并刷新 * * @param index */ private void setViewData(int index) { GridView gridView = (GridView) getNextView(); OneScreenListAdapter adapter = new OneScreenListAdapter(mContext); adapter.setScreenData(mMenuData.getScreen(index)); gridView.setAdapter(adapter); } /** * 工厂,构造GridView为ViewSwitcher的内容 * * @author Administrator * */ class SlideViewFactory implements ViewFactory { public View makeView() { GridView gridView = new GridView(mContext); gridView.setNumColumns(3); gridView.setVerticalSpacing(20); gridView.setHorizontalSpacing(20); return gridView; } } }
OneScreenListAdapter:
package com.home.testviewswitcher; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.home.testviewswitcher.MenuData.MenuDataOneScreen; public class OneScreenListAdapter extends BaseAdapter { private MenuDataOneScreen mScreen; private LayoutInflater mInflater; public OneScreenListAdapter(Context context) { mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } 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; } public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (convertView == null) { view = mInflater.inflate(R.layout.gridview_grid, 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; } }
MenuData:
package com.home.testviewswitcher; import java.util.ArrayList; import android.graphics.drawable.Drawable; /** * 该类模拟了功能菜单的数据部分 * * @author Administrator * */ public class MenuData { /** 每一屏能够容纳的应用程序数目 */ public static final int NUMBER_IN_ONE_SCREEN = 12; /** 所有屏的集合 */ public ArrayList<MenuDataOneScreen> mScreens = new ArrayList<MenuDataOneScreen>(); /** 该类代表每个应用程序的数据部分 */ public static class DataItem { public String dataName; // 应用程序名称 public Drawable drawable; // 应用程序图标 } /** 该类代表了一个屏的所有应用程序 */ public static class MenuDataOneScreen { ArrayList<DataItem> mDataItems = new ArrayList<DataItem>(); } /** * 对该类进行赋予数据 * * @param dataItems */ 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); } } /** * 获取屏数 * * @return */ public int getScreenNumber() { return mScreens.size(); } /** * 根据屏的索引,获取某个屏的数据 * * @param screenIndex * @return */ public MenuDataOneScreen getScreen(int screenIndex) { return mScreens.get(screenIndex); } }
这里使用的动画和前面自定义一个ImageSwitcher使用的动画一样,就不再给出。
gridview_grid.xml:(每个GridView里面的布局):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/textview" android:layout_below="@id/imageview" android:layout_alignLeft="@id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>