使用ViewSwitcher模拟手机屏幕应用分屏和切换

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






 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u010142437

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值