随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)、QQ技术交流群(183198395)。
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>