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

转载的老板请注明出处: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值