安卓学习笔记---使用ViewPager+Fragment实现切换动态加载刷新数据,有坑,需要自己做才能发现

当一个页面有3个Tab,可以滑动切换,自然想到了使用ViewPager+Fragment实现切换,如果每个Tab的页面都一致,只是请求接口的时候参数不一样的话,就自然会想到在Fragment实现动态加载数据。说的很简单,但是实际操作之后发现有很多的坑啊,各种问题,不能正常加载,或者页面没有显示等情况,现在记录一下,以免日后遇到相同的问题。

在Fragment中设置:

第一步:需要在Fragment进行实例化

主要是统一Fragment的实例化工作。如果Fragment需要外部传递参数,在此函数中要构造相关参数,这一步是必须的

public static MartialMoreFragment newInstance(String categoryArm) {
    MartialMoreFragment fragment = new MartialMoreFragment();
    Bundle bundle = new Bundle();
    bundle.putString("category", categoryArm);
    fragment.setArguments(bundle);
    return fragment;
}

第二步:在Fragment中参数的获取

一要在onCreate方法获取参数。我写在了onCreateView中获取参数,但是看到网上说在onCreate方法中比较好,而onCreateView方法在某些状态下并不会被调用,导致数据丢失。

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle args = getArguments();
    if (args != null) {
        this.category = args.getString("category");

    }
    LoggerUtil.i(TAG, "onCreate--category--->" + category);
}

第三步:在Fragment中参数的更新

更新Fragment内部成员变量的同时也要更新bundleArgs参数中的值。此步骤要和ViewPager适配器配合使用,实现Fragment动态刷新。这一步很关键,当滑动或者点击切换的时候就需要参数的更新,重新请求数据,否则就没有意义啦。

public void updateArguments(String categoryArm) {
    this.category = categoryArm;

    Bundle bundleArgs = getArguments();
    if (bundleArgs != null) {
        bundleArgs.putString("category", categoryArm);
    }
    LoggerUtil.i(TAG, "updateArguments--category--->" + category);
}

在ViewPager的适配器FragmentPagerAdapter中设置:

第一步:实现getItem方法

返回具体Fragment,并且初始化Fragment需要的参数,调用Fragment的newInstance()方法

@Override
public Fragment getItem(int position) {
    return MartialMoreFragment.newInstance(categorys[position]);
}

第二步:实现instantiateItem方法

如果需要动态刷新数据,就需要此方法,并且仅能在此方法里,不能是getItem。否则调用notifyDataSetChanged无效。

@Override
public Object instantiateItem(ViewGroup container, final int position) {
    MartialMoreFragment fragment  = (MartialMoreFragment) super.instantiateItem(container, position);
    fragment.updateArguments(categorys[position]);
    LoggerUtil.i("MartialMoreNoticeFragme","instantiateItem-->position-->"+position);
    return fragment;
}
第三步:实现getItemPosition方法

返回PagerAdapter.POSITION_NONE保证调用notifyDataSetChanged刷新Fragment。

@Override
public int getItemPosition(Object object) {
    return PagerAdapter.POSITION_NONE;
}
第四步:也要实现ViewPager切换监听 OnPageChangeListener 方法

下面附上整体的Activity里面的代码,需要的话可以复制,保留自己需要的功能即可。

1.MartialMoreActivity:

import android.os.Bundle;
import android.support.v4.app.Fragment;
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.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
public class MartialMoreActivity extends BaseActivity implements View.OnClickListener {

    private ImageView img_martial_more_back;
    private TextView[] textViews;
    private TextView[] textViewLines;
    private ViewPager viewPager_martial;

    private String[] categorys = new String[]{"notice", "activity", "honor"};
    private String martialName;
    private TextView tv_title_name;
    @Override
    public int getContentView() {
        return R.layout.activity_martial_more;
    }

    @Override
    public void initViews(Bundle savedInstanceState) {

        martialName=getIntent().getStringExtra("martialName");

        tv_title_name=(TextView)findViewById(R.id.tv_title_name);
        img_martial_more_back = (ImageView) findViewById(R.id.img_martial_more_back);
        viewPager_martial = (ViewPager) findViewById(R.id.viewPager_martial);
        tv_title_name.setText(martialName);

        setTextviews();
        setTextviewLines();
        img_martial_more_back.setOnClickListener(this);

        NewsFragmentPagerAdapter mAdapetr = new NewsFragmentPagerAdapter(getSupportFragmentManager());
        viewPager_martial.setAdapter(mAdapetr);
        viewPager_martial.addOnPageChangeListener(pageListener);

        viewPager_martial.setCurrentItem(0);//设置当前页数(页面返回时,可以设置页数)
    }

    @Override
    public void initDatas() {

    }
    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.img_martial_more_back:
                MartialMoreActivity.this.finish();
                break;
        }
    }

    public class NewsFragmentPagerAdapter extends FragmentPagerAdapter {


        NewsFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return categorys.length;
        }

        @Override
        public Fragment getItem(int position) {
            return MartialMoreFragment.newInstance(categorys[position]);
        }

        @Override
        public int getItemPosition(Object object) {
            return PagerAdapter.POSITION_NONE;
        }

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            MartialMoreFragment fragment  = (MartialMoreFragment) super.instantiateItem(container, position);
            fragment.updateArguments(categorys[position]);
            LoggerUtil.i("MartialMoreNoticeFragme","instantiateItem-->position-->"+position);
            return fragment;
        }
    }

    /**
     * ViewPager切换监听方法
     */
    public ViewPager.OnPageChangeListener pageListener = new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageSelected(int position) {
            resetlaybg();
            textViews[position].setTextColor(getResources().getColor(
                    R.color.a32DBC1));
            textViewLines[position].setBackgroundColor(getResources().getColor(R.color.a32DBC1));

            LoggerUtil.i("MartialMoreNoticeFragme","onPageSelected-->position-->"+position);
        }
    };

    /**
     * 点击linerlayout实现切换fragment的效果
     */
    public void matialLayoutOnclick(View v) {
        // 每次点击都重置linearLayouts的背景、textViews字体颜色
        switch (v.getId()) {
            case R.id.linear_notice:
                resetlaybg();
                viewPager_martial.setCurrentItem(0);
                textViews[0].setTextColor(getResources().getColor(
                        R.color.a32DBC1));
                textViewLines[0].setBackgroundColor(getResources().getColor(
                        R.color.a32DBC1));
                break;

            case R.id.linear_activity:
                resetlaybg();
                viewPager_martial.setCurrentItem(1);
                textViews[1].setTextColor(getResources().getColor(
                        R.color.a32DBC1));
                textViewLines[1].setBackgroundColor(getResources().getColor(
                        R.color.a32DBC1));

                break;
            case R.id.linear_honor:
                resetlaybg();
                viewPager_martial.setCurrentItem(2);
                textViews[2].setTextColor(getResources().getColor(
                        R.color.a32DBC1));
                textViewLines[2].setBackgroundColor(getResources().getColor(
                        R.color.a32DBC1));
                break;

        }
    }
    /**
     * 初始化textview
     */
    public void setTextviews() {
        textViews = new TextView[3];
        textViews[0] = (TextView) findViewById(R.id.tv_notice);
        textViews[1] = (TextView) findViewById(R.id.tv_activity);
        textViews[2] = (TextView) findViewById(R.id.tv_honor);
        textViews[0].setTextColor(getResources()
                .getColor(R.color.a32DBC1));
    }

    /**
     * 初始化textviewLine
     */
    public void setTextviewLines() {
        textViewLines = new TextView[3];
        textViewLines[0] = (TextView) findViewById(R.id.tv_notice_line);
        textViewLines[1] = (TextView) findViewById(R.id.tv_activity_line);
        textViewLines[2] = (TextView) findViewById(R.id.tv_honor_line);
        textViewLines[0].setBackgroundColor(getResources()
                .getColor(R.color.a32DBC1));
    }


    /**
     * 重置textViews textViewLines
     */
    public void resetlaybg() {
        for (int i = 0; i < 3; i++) {
            textViews[i].setTextColor(getResources().getColor(R.color.a999999));
            textViewLines[i].setBackgroundColor(getResources().getColor(R.color.f4f4f4));
        }

    }
}
2.activity_martial_more.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"
    android:orientation="vertical"
    android:background="@color/white"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen60">
        <ImageView
            android:id="@+id/img_martial_more_back"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@drawable/study_play_back"
            android:layout_marginLeft="@dimen/dimen15"
            android:layout_centerVertical="true"
            />
        <TextView
            android:id="@+id/tv_title_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/a252525"
            android:textSize="@dimen/size18"
            android:layout_centerInParent="true"
            />
    RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >

        <LinearLayout
            android:id="@+id/linear_notice"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center"
            android:onClick="matialLayoutOnclick"
            >
            <TextView
                android:id="@+id/tv_notice"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="查看1"
                android:textSize="@dimen/size14"
                android:textColor="@color/a32DBC1"
                />
            <TextView
                android:id="@+id/tv_notice_line"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dimen2"
                android:background="@color/a32DBC1"
                android:layout_marginTop="@dimen/dimen13"
                />

        LinearLayout>
        <LinearLayout
            android:id="@+id/linear_activity"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center"
            android:onClick="matialLayoutOnclick"
            >
            <TextView
                android:id="@+id/tv_activity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="查看2"
                android:textSize="@dimen/size14"
                android:textColor="@color/a999999"
                />
            <TextView
                android:id="@+id/tv_activity_line"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dimen2"
                android:background="@color/f4f4f4"
                android:layout_marginTop="@dimen/dimen13"
                />
        LinearLayout>
        <LinearLayout
            android:id="@+id/linear_honor"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center"
            android:onClick="matialLayoutOnclick"
            >
            <TextView
                android:id="@+id/tv_honor"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="查看3"
                android:textSize="@dimen/size14"
                android:textColor="@color/a999999"
                />
            <TextView
                android:id="@+id/tv_honor_line"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dimen2"
                android:background="@color/f4f4f4"
                android:layout_marginTop="@dimen/dimen13"
                />
        LinearLayout>
    LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager_martial"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

LinearLayout>

至此Activity已经完成,下面是Fragment的数据

在Fragmnet中使用了SwipeRefreshLayout+RecyclerView实现下拉刷新和上拉加载功能。

在Fragmnet服用需要注意的是:

1:有时候我发现数据会重复加载,解决这个问题可以使用以下方法:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //ViewPage + Fragment 防止Fragment 重复加载问题
    if (view == null) {
        view = inflater.inflate(R.layout.activity_martial_more_fragment, container, false);

        initView();//初始化
    }
    ViewGroup parent = (ViewGroup) view.getParent();
    if (parent != null) {
        parent.removeView(view);
    }
    return view;
}

2.因为在RecycleView还使用了GridView,之前遇到的问题是,当使用GridView展示图片的时候,如果没有全部加载完也就是有空白的时候,点击空白的地方不能跳转,这个问题可以查看

https://blog.csdn.net/juhua2012/article/details/79992280

以下是MartialMoreFragment中的代码:主要显示几个比较重要的

//1、Fragment的实例化
public static MartialMoreFragment newInstance(String categoryArm) {
    MartialMoreFragment fragment = new MartialMoreFragment();
    Bundle bundle = new Bundle();
    bundle.putString("category", categoryArm);
    fragment.setArguments(bundle);
    return fragment;
}

//2、Fragment参数的获取
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Bundle args = getArguments();
    if (args != null) {
        this.category = args.getString("category");

    }
    LoggerUtil.i(TAG, "onCreate--category--->" + category);
}

//3、Fragment参数的更新
public void updateArguments(String categoryArm) {
    this.category = categoryArm;

    Bundle bundleArgs = getArguments();
    if (bundleArgs != null) {
        bundleArgs.putString("category", categoryArm);
    }
    LoggerUtil.i(TAG, "updateArguments--category--->" + category);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //ViewPage + Fragment 防止Fragment 重复加载问题
    if (view == null) {
        view = inflater.inflate(R.layout.activity_martial_more_fragment, container, false);

        initView();//初始化 在这个方法进行获取控件等操作
    }
    ViewGroup parent = (ViewGroup) view.getParent();
    if (parent != null) {
        parent.removeView(view);
    }
    return view;
}
以上基本是自己在实现ViewPager+Fragmnet,在Fragment里面使用 SwipeRefreshLayout+RecyclerView遇到的问题,先记录到这里吧,自己觉得这种问题会经常遇到的,写个心得比较好,好记性不如烂笔头。

你可能感兴趣的:(RecyclerView应用)