滑动页面的一个例子

来源:互联网 发布:北京海量数据 编辑:程序博客网 时间:2024/05/19 22:05

1. 目的

实现一个Tab列表、多个页面滑动的效果。涉及到如下几个概念:

  • ViewPager: 所有页面的容器,里边通过适配器安装多个Fragment
  • ActionBar:页面上面的ActionBar,这里的风格是一组TAB
  • ActionBar.Tab:页面上面的tab列表,通过选择每个Tab导航到对应的页面,即Fragment
  • FragmentActivity:活动页面的主Activity要继承自FragmentActivity类。因为在创建给ViewPager使用的FragmentPagerAdapter的时候,要调用FragmentActivity的getSupportFragmentManager()方法
  • FragmentPagerAdapter:是ViewPager和一系列Fragment对象之间的适配器
  • Fragment: 实际的每一页现实的内容。可以和其他的Activity联系起来,此属于更进一步的用法,所以本文不涉及。
  • TabListener:监听页面最上面的Tab选择事件,从而通过FragmentPagerAdapter更新Fragment对象。


以上这些概念,通过具体一步步模仿一个小例子即可了解。


2. 参考资料

本文参考: 利用ViewPager+Fragment+actionbar实现可左右滑动的Action Tab


3. 效果


4. 代码

4.1 ViewPager对应的布局文件

activity_main.xml --------- ADT自动生成的不能满足要求,修改如下:

<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.hellofragment.MainActivity"/>

4.2 Fragment布局文件

fragment_main.xml --- ADT自动生成的基础上,增加了一个id属性,从而代码中可以引用这个TextView对象。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.example.hellofragment.MyFragment" >    <TextView        android:id="@+id/text_view_id"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" /></RelativeLayout>

4.3 字符串资源

strings.xml---- ADT自动生成,未作修改

<?xml version="1.0" encoding="utf-8"?><resources>    <string name="app_name">HelloFragment</string>    <string name="hello_world">Hello world!</string>    <string name="action_settings">Settings</string></resources>

4.4 Java代码

package com.example.hellofragment;import java.util.ArrayList;import java.util.List;import android.app.ActionBar;import android.app.ActionBar.Tab;import android.app.ActionBar.TabListener;import android.app.FragmentTransaction;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.util.Log;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;/** * We hard code in this example, the number of action tab and fragment is 3. *  */public class MainActivity extends FragmentActivity implements TabListener {private final String TAG = "MainActivity";    private ActionBar actionBar = null;    private ViewPager viewPager = null;        /**     * used by {@link #addTabs()} to get each page's title     */    private PagerAdapter pagerAdapter = null;      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.d(TAG, "onCreate()");                initActionBar();        initViewPager();        addTabs();    }private void initActionBar() {Log.d(TAG, "initActionBar()");actionBar  = this.getActionBar();                actionBar.setHomeButtonEnabled(false);        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        actionBar.setDisplayShowTitleEnabled(false);        actionBar.setDisplayShowHomeEnabled(false);}/** * addTab() will trigger the {@link #onTabSelected()}. *  * So initialize ViewPager first. */private void addTabs() {Log.d(TAG, "addTabs()");for (int i = 0; i < 3/*hard code here*/; i++) {actionBar.addTab(actionBar.newTab()    .setText(pagerAdapter.getPageTitle(i))    .setTabListener(this));    }}    private void initViewPager() {    Log.d(TAG, "initViewPager()");        viewPager = (ViewPager)this.findViewById(R.id.container);            // set ViewPager's adapter, which includes the fragment creation    pagerAdapter = new MyFragmentPagerAdapter(this.getSupportFragmentManager());    viewPager.setAdapter(pagerAdapter);        // set default item        viewPager.setCurrentItem(0);                // set listener        viewPager.setOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageSelected(int position) {Log.d(TAG, "OnPageChangeListener, onPageSelected(), position=" + position);actionBar.setSelectedNavigationItem(position);}        });}        /** * Delete the auto generated code to disable the option menu items. */    @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;    }/** * Delete the auto generated code to disable the option menu items. */    @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);    }    /**     * A placeholder fragment containing a simple view.     *      */    public static class MyFragment extends Fragment {    private final String DEFAULT_TEXT = "default text";    private String text = DEFAULT_TEXT; //used by textView    private TextView textView = null;        /**     * This title is used by Pager     */    private final String DEFAULT_TITLE = "default title";    private String title = DEFAULT_TITLE;            public MyFragment() {        }        private void setText(String text) {        this.text = text;        }                public String getText() {        return text;        }                public void setTitle(String title) {        this.title = title;        }                public String getTitle() {        return title;        }                @Override        public View onCreateView(LayoutInflater inflater, ViewGroup container,                Bundle savedInstanceState) {            View rootView = inflater.inflate(R.layout.fragment_main, container, false);            textView = (TextView)rootView.findViewById(R.id.text_view_id);            textView.setText(text);                        return rootView;        }            }    public class MyFragmentPagerAdapter extends FragmentPagerAdapter {    private List<MyFragment> fragments = new ArrayList<MyFragment>();    public MyFragmentPagerAdapter(FragmentManager fm) {super(fm);        createFragments();}private void createFragments() {    String[] texts = new String[] {    "First fragment", "Second fragment", "Third fragment"    };        String[] titles = new String[] {    "First tab", "Second tab", "Third tab"    };    MyFragment fragment = null;for (int i = 0; i < 3; i++) {fragment = new MyFragment();fragment.setText(texts[i]);fragment.setTitle(titles[i]);fragments.add(fragment);}}@Overridepublic Fragment getItem(int position) {Log.d(TAG, "MyFragmentPagerAdapter, getItem(), position=" + position);return fragments.get(position);}@Overridepublic int getCount() {return fragments.size();}    /** * This title is same as fragment's title, used by {@link MainActivity#addTabs()}  * to set corresponding tab's text. */@Overridepublic String getPageTitle(int position) {Log.d(TAG, "MyFragmentPagerAdapter, getPageTitle(), position=" + position);return fragments.get(position).getTitle();}    }@Overridepublic void onTabSelected(Tab tab, FragmentTransaction ft) {Log.d(TAG, "onTabSelected()");viewPager.setCurrentItem(tab.getPosition()); }@Overridepublic void onTabUnselected(Tab tab, FragmentTransaction ft) {}@Overridepublic void onTabReselected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stub}}

5. 打印日志


6. 一点说明

主要的步骤是:

  • 设置ActionBar的属性,比如tab显示方式等;
  • 创建ViewPager对象,并设置其一些属性,重点是设置适配器,这个适配器会和Fragment关联起来
  • 创建ActionBar的Tab列表。


Fragment和Tab的联动,一方面,是通过ViewPager的FragmentPagerAdapter对象来实现的:当页面滑动的时候,适配器会自动更新fragment(getItem()方法);另一方面,ViewPagerde的OnPageChangeListener()调用ActionBar的setSelectedNavigationItem()方法来更新Tab。

反过来,当Tab变化的时候,通过实现TabListener接口的onTabSelected()方法,去调用ViewPager的setCurrentItem(),进而触发OnPageChangeListener()。

0 0
原创粉丝点击