自学Android之UI组件:(四)Fragment的基本使用(下)

来源:互联网 发布:java multieditor 编辑:程序博客网 时间:2024/06/08 11:02

转载的老板请注明出处:http://blog.csdn.net/cc_xz/article/details/63735864 万分感谢!

前言:

本篇为Fragment系列的第三篇,也是最后一篇,本篇主要介绍Fragment配合ViewPager实现滑动翻页的功能,中间也会穿插一些自定义View的知识点。注意啦,代码中所用到的图片在Demo中。

在本篇中,你将了解到:
1.简单的自定义View。
2.如何使用ViewPager。
3.通过FragmentPagerAdapter来管理Fragment。
4.根据当前显示的Fragment修改标题。


代码说明:

本篇中的理论知识不多,所以无需废话,直接来看一下本篇代码的思路:
1.首先创建一个组合控件,设定布局以及初始化。
2.对需要使用的方法,在组合控件中进行定义。
3.创建ViewPagerAdapter。
4.在MainActivity的布局中进行排版。
5.创建各个Fragment。
6.初始化组件ID、组件数组、Fragment、以及将Fragment应用到ViewPager中。
7.初始化组件显示内容,并且设置组件的显示格式。
8.设置ViewPager监听器,设置当滑动时翻页并修改标题样式。
9.给标题组件设置监听器,通过FragmentViewPagerAdapter进行跳转Fragment。


再来看一眼效果图,标题的样式我可是很满意的,哈哈!

这里写图片描述

另外,系统状态栏下面可能会看到一条灰线,这好像是截图时留下来的,截了好几次也都是这样,在模拟器上没有这个的。

详细代码解析:
以下代码是在NavigationBarTop的布局文件中写入:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/LinearLayout"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#f4f4f4"    android:orientation="vertical">    <ImageView        android:id="@+id/ImageView"        android:layout_width="45dp"        android:layout_height="0dp"        android:layout_gravity="center"        android:layout_weight="3" />    <TextView        android:id="@+id/TextView"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1.5"        android:gravity="center"        android:textColor="#898989"        android:textSize="12sp"        android:layout_marginBottom="5dp"/></LinearLayout>

以下代码是在新建的NavigationBarTop中写入:

public class NavigationBarTop extends LinearLayout {    private ImageView mImageView;    private TextView mTextView;    private LinearLayout mLinearLayout;    public NavigationBarTop(Context context, AttributeSet attrs) {        super(context, attrs);        LayoutInflater.from(context).inflate(R.layout.navigation_bar_top, this, true);        mTextView = (TextView) findViewById(R.id.TextView);        mImageView = (ImageView) findViewById(R.id.ImageView);        mLinearLayout = (LinearLayout) findViewById(R.id.LinearLayout);    }}


1.1.首先创建一个类,继承自LinearLayout。之所以不是继承自某个组件,是因为我们希望将不同的组件组合成一个使用,
1.2.只使用现有组件的功能即可,无需在组件原有功能的基础上添加新的功能。
2.1.首先创建所需的三个组件变量,分别是用于显示图标的ImageView,显示文字的TextView。
2.2.而如果希望更改自定义组件的背景,直接在LinearLayout中修改更合适。
3.1.由于我们所需的功能比较少,所以在强制要求的构造方法中只添加Context和AttributeSet即可。
3.2.如果我们希望在代码中使用这个自定义组件(组成的布局),就需要通过LayoutInflater来获取它对应的布局文件。
3.3.必须要指定该布局的父布局,并且在自定义组件发生变化时通知其父布局(this代表父布局即本身),并且获取3个组件的ID。

以下代码是在NavigationBarTop中写入:

    public void setText(String string) {        mTextView.setText(string);    }    public void setTextSize(int i) {        mTextView.setTextSize(i);    }    public void setTextColor(String color) {        mTextView.setTextColor(Color.parseColor(color));    }    public void setImage(int image) {        mImageView.setImageResource(image);    }    public void setBackground(String color) {        mLinearLayout.setBackgroundColor(Color.parseColor(color));    }    public void setMargins(int left, int top, int right, int bottom) {        LinearLayout.LayoutParams layoutParams = (LayoutParams) mImageView.getLayoutParams();        layoutParams.setMargins(left, top, right, bottom);        mImageView.setLayoutParams(layoutParams);    }


1.1.其实需要的功能很简单,只是动态修改组件文字、字体大小、颜色等。之所以不能在MainActivity中调用这些方法,是因为:
1.2.在MainActivity来看,NavigationBarTop是一个组件,而无需去关心它其中包含了哪些组件,并且如何设置这些组件。
2.1.setTextColor()是设置文字的颜色,值得注意的是,在代码中进行设置,默认是无法直接使用RGB代码的,即#FF00。
2.2.所以需要Color类来对RGB代码进行转换,当然你也可以选择int类型的16进制颜色代码,或者调用Color中自带的颜色。
2.3.setBackground()是用来设置按钮的背景颜色,之前是使用指向标的方式,但是感觉实现的效果颜值一般,就换成了:当按钮被点击,就变换背景颜色。
3.1.比较难以理解的是setMargins(),这是因为选择的图片规格一点差异,但由于是自定义组件,无法直接在Xml布局文件中定义marginsTop等属性。
3.2.而ImageView在代码中默认无法实现marginsTop等属性的功能。该方法接收的3个参数,分别为左上右下,用来设置填充边缘。
3.3.值得注意的是,之所以使用LinearLayout.LayoutParams是因为该组件是继承自LinearLayout的。
3.4.同理,如果是继承自ViewGroup等,则选择ViewGroup.LayoutParams。
3.5.该对象接收所需填充边缘的组件的布局参数,并且通过自身的setMargins()对布局参数进行设置。(就是当前组件左上右下现在分别填充了多少)
3.6.接着设置布局参数的填充数据,最后将设置完成的布局参数添加到ImageView中即可。

以下代码是在新建的FragmentViewPagerAdapter中写入:

public class FragmentViewPagerAdapter extends FragmentPagerAdapter {    private List<Fragment> mListFragment;    public FragmentViewPagerAdapter(FragmentManager fm, ArrayList<Fragment> list) {        super(fm);        mListFragment = list;    }    @Override    public Fragment getItem(int position) {        return mListFragment.get(position);    }    @Override    public int getCount() {        return mListFragment.size();    }}


1.在ListView中使用过Adapter,而FragmentPagerAdapter也是同样的道理,甚至相关方法都同ListView的Adapter相同。
2.通过构造方法可以看到,是将Fragment的创建和管理都交给了父类,所以我们在本次代码中无需显式的对Fragment进行管理。
3.其他的都比较好理解,首先getItem()会返回当前显式的Fragment,getCount()会返回一共需要显示多少个Fragment。
4.如此Adapter便设置完毕,甚至在使用的时候会更简单!

以下代码是在HomePageFragment的布局文件中写入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/home_page_fragment"    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="demo.demo02.Fragment.HomePageFragment">    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="这是HomePageFragment"        android:textColor="#36c7de"        android:textSize="24sp"/></RelativeLayout>

以下代码是在新建的HomePageFragment中写入:

public class HomePageFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.home_page_fragment,null);        return view;    }}

以下代码是在新建的ClassifyFragment的布局文件中写入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/classify_fragment"    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="demo.demo02.Fragment.ClassifyFragment">    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="这是ClassifyFragment"        android:textColor="#36c7de"        android:textSize="24sp"/></RelativeLayout>

以下代码是在ClassifyFragment中写入:

public class ClassifyFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.classify_fragment,null);        return view;    }}

以下代码是在NewestFragment的布局文件中写入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_newest_fragment"    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="demo.demo02.Fragment.NewestFragment">    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="这是NewestFragment"        android:textColor="#36c7de"        android:textSize="24sp"/></RelativeLayout>

以下代码是在NewestFragment中写入:

public class NewestFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.newest_fragment,null);        return view;    }}

以下代码是在MyFragment的布局文件中写入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_my_fragment"    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="demo.demo02.Fragment.MyFragment">    <TextView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="这是MyFragment"        android:textColor="#36c7de"        android:textSize="24sp"/></RelativeLayout>

以下代码是在MyFragment中写入:

public class MyFragment extends Fragment {    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.my_fragment,null);        return view;    }}


以上是Fragment的代码,非常简单,基本不用做什么解释了。

以下代码是在MainActivity的布局文件中写入:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <LinearLayout        android:id="@+id/LinearLayoutTop"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="1"        android:orientation="horizontal">        <demo.demo02.View.NavigationBarTop            android:id="@+id/NavigationBarHomePage"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1" />        <demo.demo02.View.NavigationBarTop            android:id="@+id/NavigationBarNewest"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1" />        <demo.demo02.View.NavigationBarTop            android:id="@+id/NavigationBarClassify"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1" />        <demo.demo02.View.NavigationBarTop            android:id="@+id/NavigationBarMy"            android:layout_width="0dp"            android:layout_height="match_parent"            android:layout_weight="1" />    </LinearLayout>    <TextView        android:layout_width="match_parent"        android:layout_height="1sp"        android:background="#939393" />    <android.support.v4.view.ViewPager        android:id="@+id/ViewPager"        android:layout_width="match_parent"        android:layout_height="0dp"        android:layout_weight="12" /></LinearLayout>

以下代码是在MainActivity中写入:

private void initView() {        mBarHomePage = (NavigationBarTop) findViewById(R.id.NavigationBarHomePage);        mBarNewest = (NavigationBarTop) findViewById(R.id.NavigationBarNewest);        mBarClassify = (NavigationBarTop) findViewById(R.id.NavigationBarClassify);        mBarMy = (NavigationBarTop) findViewById(R.id.NavigationBarMy);        mViewPager = (ViewPager) findViewById(R.id.ViewPager);        mNavigationBarArray = new NavigationBarTop[]{mBarHomePage, mBarNewest, mBarClassify, mBarMy};        BarImage = new int[]{R.drawable.im_home_blue, R.drawable.im_newest_blue,                R.drawable.im_classify_blue, R.drawable.im_my_blue};        ArrayList<Fragment> mListFragment = new ArrayList<>();        mListFragment.add(new HomePageFragment());        mListFragment.add(new NewestFragment());        mListFragment.add(new ClassifyFragment());        mListFragment.add(new MyFragment());        FragmentViewPagerAdapter adapter = new FragmentViewPagerAdapter(getSupportFragmentManager(), mListFragment);        mViewPager.setAdapter(adapter);        mViewPager.setOnPageChangeListener(this);    }


1.本部分比较好理解,首先是获取自定义组件和ViewPager的ID。
2.接着分别将自定义组件和被选中时显示的图片放到数组中,这是用于在ViewPager进行翻页时通过ViewPager给出的位置进行设置的。
3.接着将初始化完成的Fragment作为参数,添加到ArrayList中,并将本Activity的Fragment管理器和载有Fragment的List添加到Adapter中。
4.接着为ViewPager应用Adapter。即Adapter应用Fragment,而ViewPager应用Adapter。
5.最后为ViewPager注册滑动监听事件。(需要继承ViewPager.OnPageChangeListener接口)

以下代码是在MainActivity中写入:

private void initBar() {        mBarHomePage.setImage(R.drawable.im_home);        mBarNewest.setImage(R.drawable.im_newest);        mBarClassify.setImage(R.drawable.im_classify);        mBarMy.setImage(R.drawable.im_my);        mBarHomePage.setTextColor("#898989");        mBarNewest.setTextColor("#898989");        mBarClassify.setTextColor("#898989");        mBarMy.setTextColor("#898989");        mBarHomePage.setBackground("#f4f3f3");        mBarNewest.setBackground("#f4f3f3");        mBarClassify.setBackground("#f4f3f3");        mBarMy.setBackground("#f4f3f3");    }


1.这部分是初始化组件格式,即添加图片(默认图片),并且设置默认的字体颜色。
2.由于选择了当点击后自定义组件背景将发生变化,所以无法在Layout中直接定义属性。

以下代码是在MainActivity中写入:

private void initBarStyle() {        mBarHomePage.setTextSize(13);        mBarHomePage.setText("首页");        mBarNewest.setText("最新");        mBarClassify.setText("分类");        mBarMy.setText("我的");        mBarNewest.setMargins(0, 10, 0, 0);        mBarClassify.setMargins(0, 10, 0, 0);        mBarMy.setMargins(0, 10, 0, 0);    }


3.这部分是定义了自定义组件的显示内容,第一个字体大小,是由于”首页”二个字相对其他字会看起来小一些,所以放大一号。
4.接着是添加组件显示的文字,并且根据图片的不同,设置向下填充10,而第一张图片则无需此操作。
5.如果你选择了其他图片的话,则可以根据图片的不同来设置setMargins()。

以下代码是在MainActivity中写入:

    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Override    public void onPageSelected(int position) {        initBar();        mNavigationBarArray[position].setTextColor("#72C9F5");        mNavigationBarArray[position].setImage(BarImage[position]);        mNavigationBarArray[position].setBackground("#ecebeb");    }    @Override    public void onPageScrollStateChanged(int state) {    }


1.当继承了OnPageChangeListener接口后,则会要求重写以下3个方法。
2.onPageScrolled()是当用户发起滑动时所执行的方法。(拖动前)
3.onPageSelected()是当用户滚动操作执行完毕后所执行的方法。(拖动后)
4.onPageScrollStateChanged()是滚动状态改变时调用的方法。用于发现当用户开始拖动。(拖动中)
5.1.来看我们所需要关心的地方,首先需要初始化所有组件的字体颜色、图片等,这是因为,
5.2.当滚动结束后,需要将特殊的颜色和背景设置到当前显示的页对应的组件中。
5.3.如果不进行初始化,当翻过所有页后,所有的组件都将变成特殊颜色和图片的样式。
5.4.接着分别设置与当前显示的页对应的组件的字体颜色、图片和背景颜色。

以下代码是在MainActivity中写入:

private void navigationBarClickListener() {        mBarHomePage.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mViewPager.setCurrentItem(0);            }        });        mBarNewest.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mViewPager.setCurrentItem(1);            }        });        mBarClassify.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mViewPager.setCurrentItem(2);            }        });        mBarMy.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mViewPager.setCurrentItem(3);            }        });    }


1.1.其实LinearLayout也可以有点击事件,虽然它只是个布局(NavigationBarTop是继承自LinearLayout)。
1.2.这是因为点击事件是在View中定义的,而所有的组件的父类都是View。
2.可以看到,通过setCurrentItem即可打开期望的Fragment,这个很简单。但是需要注意两个问题。
3.1.首先,监听事件的设置你可以理解成是当编译器发现监听事件后,就将该监听事件中的代码保存起来,当条件出发后(被点击或???)就执行其中的代码。
3.2.但是这时已经不是通过onCreate()这里了,因为onCreate()只有在Activity创建才调用一次。
4.通常触发监听事件的条件就是被点击,但是当你通过ViewPager实现滑动时,同样可以触发监听事件。

Demo到此完毕,感谢!鼓掌!再来看(欣赏)一下效果图:
这里写图片描述

后记:

本篇其实对于Fragment方面的东西介绍的不是很多,不过也是目前大多数项目所使用的一个结构,下一篇博客我们会讨论一下RecyclerVIew方面的东西,下下篇会在本篇博客的基础上与RecyclerView相结合,做一个小玩意。

Demo传送门:http://download.csdn.net/detail/cc_xz/9786658

0 0
原创粉丝点击