您的位置:首页 > 其它

TabLayout+ViewPager+Fragment实现懒加载

2017-05-25 18:21 309 查看
在开发中经常用到TabLayout+ViewPager+Fragment的组合。如下图所示:





首先介绍一下使用方法:

xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14

<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#EF8D11"
app:tabIndicatorColor="#EF4A11"
app:tabMode="scrollable"
app:tabSelectedTextColor="#FFFFFF"
app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
app:tabTextColor="#FFFFFF" />
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

属性说明:

Android:background="#EF8D11"
背景色

app:tabIndicatorColor="#EF4A11"
tab文字下方的那条线的颜色

app:tabMode="scrollable"
如果tab过多超出屏幕宽度可以水平滚动

app:tabSelectedTextColor="#FFFFFF"
tab被选中的时候文字的颜色

app:tabTextColor="#FFFFFF"
tab未被选中时文字的颜色

app:tabTextAppearance="@style/MyTabLayoutTextAppearance"
自定义字体大小(一般使用默认即可)

1
2
3

<style name="MyTabLayoutTextAppearance" parent="TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse">
&
4000
lt;item name="android:textSize">12sp</item>
</style>

Java 代码

1
2
34
5
6
7
8
9

private void setTabs() {
HomePagerAdapter homePagerAdapter = new HomePagerAdapter(getSupportFragmentManager());
homePagerAdapter.addTab(new FragmentOne(), "tab1");
homePagerAdapter.addTab(new FragmentTwo(), "tab2");
homePagerAdapter.addTab(new FragmentThree(), "tab3");
viewPager.setAdapter(homePagerAdapter);
//把tabLayout和Viewpager关联起来
tabLayout.setupWithViewPager(viewPager);
}

HomePagerAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
1415
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

package com.jetsun.demo;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import java.util.ArrayList;
import java.util.List;

/**
* Overview:
*/
public class HomePagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments = new ArrayList<>();
private List<String> titles = new ArrayList<>();

public HomePagerAdapter(FragmentManager fm) {
super(fm);
}

public void addTab(Fragment fragment, String title) {
fragments.add(fragment);
titles.add(title);
}

@Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}

@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public int getCount() {
return fragments.size();
}
}


懒加载机制

默认情况下,当显示tab1时,tab2已经加载了(已经调用了生命周期的oncreate,oncreateview,onactivitycreate,onresume方法),也就是默认加载当前fragment两边的一个fragment。加载的个数可以通过viewpager.setoffscreenpagelimit方法控制,模式是viewpager.setoffscreenpagelimit(1).最少也就是1,即使设置成0也默认预加载一个。假如现在的需求是要在fragment显示出来的时候才加载数据,那么通过viewpager.setoffscreenpagelimit方法是无法做到控制的。

下面就介绍另外一种方法来实现这种需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
1415
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70

package com.jetsun.demo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
* Overview:
*/
public class FragmentDemo extends Fragment {

@Bind(R.id.recycler_view)
RecyclerView recyclerView;
@Bind(R.id.swipe_refresh_layout)
SwipeRefreshLayout swipeRefreshLayout;
//控件是否已经初始化
private boolean isCreateView = false;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null, false);
ButterKnife.bind(this, view);

initViews();
isCreateView = true;
return view;
}

private void initViews() {
//初始化控件
}

//此方法在控件初始化前调用,所以不能在此方法中直接操作控件会出现空指针
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isCreateView) {
lazyLoad();
}
}

private void lazyLoad() {
//加载数据操作
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//第一个fragment会调用
if (getUserVisibleHint())
lazyLoad();
}

@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}

在实际开发中,可以把上面的代码抽取到BaseFragment中使用。上面这个方法实现了每次fragment显示出来的时候加载数据,但是这样切换回来的时候还会重复加载,我们只需加载一次就好了。所以改进一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
1415
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

package com.jetsun.demo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
* Overview:
*/
public class FragmentDemo extends Fragment {

@Bind(R.id.recycler_view)
RecyclerView recyclerView;
@Bind(R.id.swipe_refresh_layout)
SwipeRefreshLayout swipeRefreshLayout;
//控件是否已经初始化
private boolean isCreateView = false;
//是否已经加载过数据
private boolean isLoadData = false;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, null, false);
ButterKnife.bind(this, view);

initViews();
isCreateView = true;
return view;
}

private void initViews() {
//初始化控件
}

//此方法在控件初始化前调用,所以不能在此方法中直接操作控件会出现空指针
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isCreateView) {
lazyLoad();
}
}

private void lazyLoad() {
//如果没有加载过就加载,否则就不再加载了
if(!isLoadData){
//加载数据操作
isLoadData=true;
}
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//第一个fragment会调用
if (getUserVisibleHint())
lazyLoad();
}

@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
}

#tablayout
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐