二 滑动导航" />
当前位置: 代码迷 >> Android >> 二 滑动导航
  详细解决方案

二 滑动导航

热度:141   发布时间:2016-04-28 03:09:58.0
【Android进阶】(6)Activity启动模式和窗口导航

文章出处:http://blog.csdn.net/scarthr/article/details/42145015

我们今天来看窗口导航。

一 用Activity的启动模式

如何让我们的程序在启动了好多Activity之后回到主窗口的时候关闭其他所有窗口呢?一种实现方式是使用一个List集合,每创建一个Activity就放到这个List中,当最后需要返回主窗口的时候,遍历List集合,一个一个关闭即可。今天我们来学习另一种方式,这涉及到了Activity的启动模式。

那么如何设置Activity的启动模式呢?

在Manifest中配置Activity的launchMode属性即可,一共有4个方式:

1. standard:标准的(默认的),每次都会创建一个新实例放入任务栈中。

2. singleTop:如果任务的栈顶存在该Activity实例,就会重用该实例,否则就会创建新的实例放入栈顶(即使栈中存在,只要不在栈顶就会创建新实例)

3. singleTask:如果任务的栈中存在该Activity实例,就会重用该实例,并让改实例放入栈顶,它之前上面的实例将会被移除。如果栈中没有该实例就会创建该实例。

4. singleInstance:在一个新栈中创建改实例,并让多个应用共享该栈中的该实例。一旦该模式的Activity实例存在于某个栈中,任何应用再激活改实例都会重用该栈中的改实例,效果相当与应用程序共享一个应用,不管谁激活该Activity都会进入同一个应用中。

二 滑动导航

这个一般在应用的引导界面时使用,左右滑动实现导航的效果。实现这个效果主要用到了ViewPager和FragmentPagerAdapter。
我们在创建Android工程的时候最后一步可以选择Action Bar Tabs (with ViewPager)。就可以看到这样子导航的效果。


主布局就是一个ViewPager:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/pager"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.testviewpager.MainActivity" />
然后是Activity:

package com.example.testviewpager;import java.util.Locale;import android.app.Activity;import android.app.ActionBar;import android.app.Fragment;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.support.v13.app.FragmentPagerAdapter;import android.os.Bundle;import android.support.v4.view.ViewPager;import android.view.Gravity;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class MainActivity extends Activity implements ActionBar.TabListener {	/**	 * The [email protected] android.support.v4.view.PagerAdapter} that will provide	 * fragments for each of the sections. We use a [email protected] FragmentPagerAdapter}	 * derivative, which will keep every loaded fragment in memory. If this	 * becomes too memory intensive, it may be best to switch to a	 * [email protected] android.support.v13.app.FragmentStatePagerAdapter}.	 */	SectionsPagerAdapter mSectionsPagerAdapter;	/**	 * The [email protected] ViewPager} that will host the section contents.	 */	ViewPager mViewPager;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		// Set up the action bar.		final ActionBar actionBar = getActionBar();		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);		// Create the adapter that will return a fragment for each of the three		// primary sections of the activity.		mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());		// Set up the ViewPager with the sections adapter.		mViewPager = (ViewPager) findViewById(R.id.pager);		mViewPager.setAdapter(mSectionsPagerAdapter);		// When swiping between different sections, select the corresponding		// tab. We can also use ActionBar.Tab#select() to do this if we have		// a reference to the Tab.		mViewPager				.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {					@Override					public void onPageSelected(int position) {						actionBar.setSelectedNavigationItem(position);					}				});		// For each of the sections in the app, add a tab to the action bar.		for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {			// Create a tab with text corresponding to the page title defined by			// the adapter. Also specify this Activity object, which implements			// the TabListener interface, as the callback (listener) for when			// this tab is selected.			actionBar.addTab(actionBar.newTab()					.setText(mSectionsPagerAdapter.getPageTitle(i))					.setTabListener(this));		}	}	@Override	public boolean onCreateOptionsMenu(Menu menu) {		// Inflate the menu; this adds items to the action bar if it is present.		getMenuInflater().inflate(R.menu.main, menu);		return true;	}	@Override	public boolean onOptionsItemSelected(MenuItem item) {		// Handle action bar item clicks here. The action bar will		// automatically handle clicks on the Home/Up button, so long		// as you specify a parent activity in AndroidManifest.xml.		int id = item.getItemId();		if (id == R.id.action_settings) {			return true;		}		return super.onOptionsItemSelected(item);	}	@Override	public void onTabSelected(ActionBar.Tab tab,			FragmentTransaction fragmentTransaction) {		// When the given tab is selected, switch to the corresponding page in		// the ViewPager.		mViewPager.setCurrentItem(tab.getPosition());	}	@Override	public void onTabUnselected(ActionBar.Tab tab,			FragmentTransaction fragmentTransaction) {	}	@Override	public void onTabReselected(ActionBar.Tab tab,			FragmentTransaction fragmentTransaction) {	}	/**	 * A [email protected] FragmentPagerAdapter} that returns a fragment corresponding to	 * one of the sections/tabs/pages.	 */	public class SectionsPagerAdapter extends FragmentPagerAdapter {		public SectionsPagerAdapter(FragmentManager fm) {			super(fm);		}		@Override		public Fragment getItem(int position) {			// getItem is called to instantiate the fragment for the given page.			// Return a PlaceholderFragment (defined as a static inner class			// below).			return PlaceholderFragment.newInstance(position + 1);		}		@Override		public int getCount() {			// Show 3 total pages.			return 3;		}		@Override		public CharSequence getPageTitle(int position) {			Locale l = Locale.getDefault();			switch (position) {			case 0:				return getString(R.string.title_section1).toUpperCase(l);			case 1:				return getString(R.string.title_section2).toUpperCase(l);			case 2:				return getString(R.string.title_section3).toUpperCase(l);			}			return null;		}	}	/**	 * A placeholder fragment containing a simple view.	 */	public static class PlaceholderFragment extends Fragment {		/**		 * The fragment argument representing the section number for this		 * fragment.		 */		private static final String ARG_SECTION_NUMBER = "section_number";		/**		 * Returns a new instance of this fragment for the given section number.		 */		public static PlaceholderFragment newInstance(int sectionNumber) {			PlaceholderFragment fragment = new PlaceholderFragment();			Bundle args = new Bundle();			args.putInt(ARG_SECTION_NUMBER, sectionNumber);			fragment.setArguments(args);			return fragment;		}		public PlaceholderFragment() {		}		@Override		public View onCreateView(LayoutInflater inflater, ViewGroup container,				Bundle savedInstanceState) {			View rootView = inflater.inflate(R.layout.fragment_main, container,					false);			TextView textView = (TextView) rootView					.findViewById(R.id.section_label);			textView.setText(Integer.toString(getArguments().getInt(					ARG_SECTION_NUMBER)));			return rootView;		}	}}

英文注释已经写的很详细了,大家稍微看看应该会明白的。先创建继承自FragmentPagerAdapter的SectionsPagerAdapter适配器,获取到ViewPager后,指定好刚才创建的SectionsPagerAdapter,SectionsPagerAdapter的构造方法传FragmentManager,使用Activity的getFragmentManager()就可以得到。重写了FragmentPagerAdapter的几个方法,getItem返回一个Fragment,返回当前页面正在显示的Fragment,getCount返回总共Fragment的个数,getPageTitle可以获得每一个Fragment的标题。最后用setOnPageChangeListener给ViewPager设定了监听,可以重写onPageSelected方法,返回当前Fragment的序号。如果设定监听传的参数是OnPageChangeListener接口,那么需要重写OnPageChangeListener的3个方法:onPageSelected、onPageScrollStateChanged和onPageScrolled,看方法名也应该大概知道他们的意思了吧。

三 使用Fragment实现导航

用Fragment实现导航主要用到的技术是回退栈BackStack。addToBackStack和popBackStack方法。
主布局中创建2个按钮,fragment中就一个TextView用来显示文字,直接上Activity代码:
package com.thr.testfragmentpager;import android.app.Activity;import android.app.FragmentManager;import android.app.FragmentManager.OnBackStackChangedListener;import android.app.FragmentTransaction;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity implements		OnBackStackChangedListener {	private int count = 0;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		nextFragment(false);		onBackStackChanged();	}	private void nextFragment(boolean backStackFlag) {		final FragmentManager manager = getFragmentManager();		FragmentTransaction transaction = manager.beginTransaction();		FragmentPage fragment = new FragmentPage();		transaction.add(R.id.fl, fragment);		if (backStackFlag) {			transaction.addToBackStack(manager.getBackStackEntryCount() + "");		}		transaction.commit();		manager.addOnBackStackChangedListener(this);	}	public void showNext(View v) {		if (count != 4) {			count++;			nextFragment(true);		} else {			return;		}	}	public void showPre(View v) {		if (count == 0) {			return;		} else {			count--;			FragmentManager manager = getFragmentManager();			manager.popBackStack();		}	}	@Override	public void onBackStackChanged() {		setTitle("当前是第" + (getFragmentManager().getBackStackEntryCount() + 1)				+ "页");	}}
有两个按钮控制Fragment的切换,showPre是上一个,showNext是下一个,在第一个Fragment添加进来的时候,我们用backStackFlag控制不添加到BackStack栈中,从第二个开始添加到BackStack栈中,最大数量是5,用count控制。showNext会添加一个新的Fragment至BackStack中,showPre会执行popBackStack,移除最上面的一个Fragment。
截图:


源码下载




  相关解决方案