Fragment与ViewPager

来源:互联网 发布:告白软件生成器 编辑:程序博客网 时间:2024/05/16 20:30

1.Fragment简单用法

建left和right的xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent">    <Button        android:id="@+id/button"        android:layout_gravity="center_horizontal"        android:text="button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent">    <TextView        android:layout_gravity="center_horizontal"        android:text="HAHA"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>


建立left和right的类:

public class Left extends Fragment {    @Override    public View onCreateView(LayoutInflater inf, ViewGroup container, Bundle savedInstanceState) {        View view = inf.inflate(R.layout.left,container,false);        return view;    }}
public class Right1 extends Fragment {    @Override    public View onCreateView(LayoutInflater inf, ViewGroup container, Bundle savedInstanceState) {        View view = inf.inflate(R.layout.right1,container,false);        return view;    }}

修改activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="horizontal"              android:layout_width="match_parent"              android:layout_height="match_parent" >    <fragment        android:layout_width="0dp"        android:layout_height="match_parent"        android:id="@+id/left_fragment"        android:name="com.lewanjiang.fragmenttest.Left"        android:layout_weight="1" />    <fragment        android:layout_width="0dp"        android:layout_height="match_parent"        android:id="@+id/right_fragment"        android:name="com.lewanjiang.fragmenttest.Right"        android:layout_weight="1" /></LinearLayout>



动态添加Fragment:

建Right1.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent">    <TextView        android:text="HEIHEI"        android:layout_width="wrap_content"        android:layout_height="wrap_content"/></LinearLayout>

建Right1类:

public class Right1 extends Fragment {    @Override    public View onCreateView(LayoutInflater inf, ViewGroup container, Bundle savedInstanceState) {        View view = inf.inflate(R.layout.right1,container,false);        return view;    }}

修改activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="horizontal"              android:layout_width="match_parent"              android:layout_height="match_parent" >    <fragment        android:layout_width="0dp"        android:layout_height="match_parent"        android:id="@+id/left_fragment"        android:name="com.lewanjiang.fragmenttest.Left"        android:layout_weight="1" />    <FrameLayout        android:id="@+id/right_layout"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="match_parent">    </FrameLayout></LinearLayout>

修改MainActivity:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button = (Button) findViewById(R.id.button);        replaceFragment(new Right());        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                replaceFragment(new Right1());            }        });    }    private void replaceFragment(Fragment fra) {        FragmentManager fraMan = getSupportFragmentManager();        FragmentTransaction tra = fraMan.beginTransaction();        tra.replace(R.id.right_layout,fra);        tra.commit();    }}

完成。


模拟返回栈:

tra.addToBackStack(null);


活动调用碎片中方法:

Right rigFra = (Right) getFragmentManager().findFragmentById(R.id.right);


碎片调用活动中方法:

在碎片中:MainActivity act = (MainActivity) getActivity();

同时也可以使用这个方法获取Context。



根据设备屏幕大小方向动态选择加载哪个布局:

修改activity_main.xml文件,使之保留一个left的fragment:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="horizontal"              android:layout_width="match_parent"              android:layout_height="match_parent" >    <fragment        android:layout_width="0dp"        android:layout_height="match_parent"        android:id="@+id/left_fragment"        android:name="com.lewanjiang.fragmenttest.Left"        android:layout_weight="1" /></LinearLayout>

在res目录下新建layout_large文件夹,新建名为:activity_main.xml的布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent">    <fragment        android:id="@+id/left"        android:name="com.lewanjiang.fragmenttest.Left"        android:layout_width="0dp"        android:layout_height="match_parent"        android:layout_weight="1" />    <fragment        android:id="@+id/right"        android:name="com.lewanjiang.fragmenttest.Right"        android:layout_height="match_parent"        android:layout_width="0dp"        android:layout_weight="3" /></LinearLayout>

最小宽度限定符:

新建layout-sw600dp文件夹。



综合应用——新闻应用:

1。build.gradle 中添加recyclerview支持

2.新建新闻类:News

public class News {    private String title;    private String content;    public String getTitle(){        return title;    }    public void setTitle(String title){        this.title = title;    }    public String getContent(){        return content;    }    public void setContent(String content) {        this.content = content;    }}
3.新建内容布局文件news_content_frag.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="match_parent"              android:layout_height="match_parent">    <LinearLayout        android:id="@+id/visibility_layout"        android:orientation="vertical"        android:visibility="invisible"        android:layout_width="match_parent"        android:layout_height="match_parent">        <TextView            android:id="@+id/news_title"            android:padding="10dp"            android:textSize="20sp"            android:layout_width="match_parent"            android:layout_height="wrap_content"/>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="#000" />        <TextView            android:id="@+id/news_content"            android:layout_weight="1"            android:textSize="18sp"            android:layout_width="match_parent"            android:layout_height="0dp"/>    </LinearLayout>    <View        android:layout_width="1dp"        android:layout_height="match_parent"        android:layout_alignParentLeft="true"        android:background="#000" /></LinearLayout>
4.新建内容布局类NewsContentFragment,继承Fragment:

public class NewsContentFragment extends Fragment {    private View view;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        view = inflater.inflate(R.layout.news_content_frag,container,false);        return view;    }    public void refresh(String newsTitle,String newsContent) {        View visibilityLayout = view.findViewById(R.id.visibility_layout);        visibilityLayout.setVisibility(View.VISIBLE);        TextView newsTitleText = (TextView)view.findViewById(R.id.news_title);        TextView newsContentText = (TextView)view.findViewById(R.id.news_content);        newsTitleText.setText(newsTitle);        newsContentText.setText(newsContent);    }}
5.对小屏模式支持,新建Activity:NewsContentAcitivty和相应布局文件news_content.xml:

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.lewanjiang.fragmentbestpractice.NewsContentActivity">    <fragment        android:id="@+id/news_content_fragment"        android:name="com.lewanjiang.fragmentbestpractice.NewsContentFragment"        android:layout_width="match_parent"        android:layout_height="match_parent" /></android.support.constraint.ConstraintLayout>

public class NewsContentActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.news_content);        String newsTitle = getIntent().getStringExtra("news_title");        String newsContent = getIntent().getStringExtra("news_content");        NewsContentFragment newsContentFragment = (NewsContentFragment) getSupportFragmentManager().findFragmentById(R.id.news_content_fragment);        newsContentFragment.refresh(newsTitle,newsContent);    }    public static void actionStart(Context context,String newsTitle,String newsContent) {        Intent intent = new Intent(context,NewsContentActivity.class);        intent.putExtra("news_title",newsTitle);        intent.putExtra("new_content",newsContent);        context.startActivity(intent);    }}

6.新建用于显示新闻列表的布局,news_title_frag.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="vertical"              android:layout_width="match_parent"              android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/news_title_recycler_view"        android:layout_width="match_parent"        android:layout_height="match_parent"        /></LinearLayout>
7.新建news_item.xml作为recyclerview的子布局:

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"              android:id="@+id/news_title"              android:layout_width="match_parent"              android:layout_height="wrap_content"        />
8.新建NewsTitleFragment作为展示新闻列表的碎片:

public class NewsTitleFragment extends Fragment {    private boolean isTwoPane;    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.news_title_frag,container,false);        RecyclerView newsTitleRecyclerView = (RecyclerView) view.findViewById(R.id.news_title_recycler_view);        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());        newsTitleRecyclerView.setLayoutManager(layoutManager);        NewsAdapter adapter = new NewsAdapter(getNews());        newsTitleRecyclerView.setAdapter(adapter);        return view;    }    private List<News> getNews(){        List<News> newsList = new ArrayList<>();        for(int i=1;i<=50;i++) {            News news = new News();            news.setTitle("This is news title" + i);            news.setContent("content" + i);            newsList.add(news);        }        return newsList;    }    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        if (getActivity().findViewById(R.id.news_content_layout) != null) {            isTwoPane = true;        } else {            isTwoPane = false;        }    }    class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {        private List<News> mNewsList;        class ViewHolder extends RecyclerView.ViewHolder {            TextView newsTitleText;            public ViewHolder(View view) {                super(view);                newsTitleText = (TextView)view.findViewById(R.id.news_title);            }        }        public NewsAdapter(List<News> newsList) {            mNewsList = newsList;        }        @Override        public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,parent,false);            final ViewHolder holder = new ViewHolder(view);            view.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    News news = mNewsList.get(holder.getAdapterPosition());                    if (isTwoPane) {                        NewsContentFragment newsContentFragment = (NewsContentFragment)getFragmentManager().findFragmentById(R.id.news_content_fragment);                        newsContentFragment.refresh(news.getTitle(),news.getContent());                        news.getContent();                    } else {                        NewsContentActivity.actionStart(getActivity(),news.getTitle(),news.getContent());                    }                }            });            return holder;        }        @Override        public void onBindViewHolder(ViewHolder holder,int position) {            News news = mNewsList.get(position);            holder.newsTitleText.setText(news.getTitle());        }        @Override        public int getItemCount() {            return mNewsList.size();        }    }}

9.修改activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.lewanjiang.fragmentbestpractice.MainActivity">    <fragment        android:id="@+id/news_title_fragment"        android:name="com.lewanjiang.fragmentbestpractice.NewsTitleFragment"        android:layout_width="match_parent"        android:layout_height="match_parent" /></android.support.constraint.ConstraintLayout>
10.新建layout-sw600dp支持大屏,在此文件夹下新建activity_main:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:orientation="horizontal"              android:layout_width="match_parent"              android:layout_height="match_parent">    <fragment        android:id="@+id/news_title_fragment"        android:name="com.lewanjiang.fragmentbestpractice.NewsTitleFragment"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="match_parent" />    <FrameLayout        android:id="@+id/news_content_layout"        android:layout_weight="3"        android:layout_width="0dp"        android:layout_height="match_parent">        <fragment            android:id="@+id/news_content_fragment"            android:name="com.lewanjiang.fragmentbestpractice.NewsContentFragment"            android:layout_width="match_parent"            android:layout_height="match_parent" />    </FrameLayout></LinearLayout>




2.ViewPager

ViewPager提供了几个适用于Fragment的Adapter,通常来说,定制含有Item View类型的控件都应该使用Adapter模式,因为你不知道用户的Item View是怎样的,你只能通过一个Adapter来进行抽象,让用户将具体的视图、数据通过Adapter进行操作。例如,通过getItem获取某个数据、通过getView获取每个Item View,这样一来变化的部分就交给用户来实现,控件只需关注自身的逻辑,然后通过Adapter的getView来获取每个Item View即可。

ViewPager内部同样也是维护了一个视图集合,这些视图集合横向布局,用户可以通过左右滑动来进行页面切换。

ViewPager与Fragment组合时通常会有一个指示器(ViewPagerIndicator)表明当前显示的是哪个页面。指示器与ViewPager实际上是两个视图,指示器根据ViewPager的页面数量以及提供的数据生成特定的指示器项,当ViewPager进行滑动时,指示器上的当前页面标识会随之变化。

简单用法:

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <com.viewpagerindicator.TabPageIndicator        android:id="@+id/indicator"        android:layout_height="wrap_content"        android:layout_width="match_parent        />    <android.support.v4.view.ViewPager        android:id="@+id/pager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        /></LinearLayout>

在代码中我们需要进行设置,示例如下:

public class MainActivity extends FragmentActivity {     // Tab标题     private static final String[] TITLE = new String[] { "页面1", "页面2", "页面3"};     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         //ViewPager的adapter         FragmentPagerAdapter adapter                 = new TabPageIndicatorAdapter(getSupportFragmentManager());         ViewPager pager = (ViewPager)findViewById(R.id.pager);         // 将Adapter设置给ViewPager         pager.setAdapter(adapter);         //实例化TabPageIndicator后与ViewPager进行关联         TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);         indicator.setViewPager(pager);      }    // ViewPager适配器    class TabPageIndicatorAdapter extends FragmentPagerAdapter {          public TabPageIndicatorAdapter(FragmentManager fm) {               super(fm);          }          @Override          public Fragment getItem(int position) {                 //新建一个Fragment来展示ViewPager item的内容,并传递参数                 Fragment fragment = new ItemFragment();                   Bundle args = new Bundle();                   args.putString("arg", TITLE[position]);                  fragment.setArguments(args);                  return fragment;          }        @Override        public CharSequence getPageTitle(int position) {            return TITLE[position % TITLE.length];        }        @Override        public int getCount() {            return TITLE.length;        }    }}

ViewPagerIndicator会与ViewPager进行管理,并且通过ViewPager的Adapter获取到页面数量、每个页面的标题等信息,然后绘制出指示器视图。当ViewPager滚动时,指示器视图也会发生相应的变化,以此达到指示页面切换的效果。




原创粉丝点击