关键词:
做项目的时候会我也会遇到许许多多的问题,也会失望,想放弃,那就是心态的问题了,如果遇到问题你以积极的心态去解决,我相信任何问题都不是问题,记住万事,自有方法,关键是不怕问题,去解决它,把挫折转化为经验,那才是最好的。
好了,废话不多说了,我也改讲一讲怎么实现懒加载,
先看看界面是怎样的:
暂时没有数据,不影响我们的效果,界面是一个订单的Activity,布局是上面一个自定义的TitileBar,下面是一个TabLayout,一个最下面是一个Viewpager,待会会在viewpager里面通过ViewpagerFragmentAdapter实现数据的填充
订单的Activity布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.xiemo.app.ui.OrderInfoActivity">
<net.anchong.app.view.TitleBarView
android:id="@+id/orders_titileBarView"
android:background="@color/cube_holo_blue_light"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</net.anchong.app.view.TitleBarView>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout_orders"
android:layout_below="@id/orders_titileBarView"
android:layout_width="match_parent"
android:layout_height="25dp"/>
<android.support.v4.view.ViewPager
android:layout_below="@+id/tab_layout_orders"
android:id="@+id/viewpager_orders"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
首先我们要实现的效果是,这里我是复用的同一个fragment:
我是直接点击进入我的订单页面的全部,然后一直滑动到退货,然后又滑动到全部,仅会加载当前viewpager的fragment的页面,而且仅仅加载一次,之后左右滑动都不会在加载,除非返回后重新进入。
第二个效果是:
每次滑动也仅加载当前的fragment页面,但是每次滑动都会请求,只需要在上面效果基础上修改一个代码即可,虽然频繁请求,有利于数据的实时更新
先上代码:
订单的Activity页面:
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import net.anchong.app.R;
import net.anchong.app.adapter.MyOrdersFragmentViewPagerAdapter;
import net.anchong.app.view.TitleBarView;
public class OrderInfoActivity extends FragmentActivity implements TitleBarView.TitleBarClickListener{
private TitleBarView ordersTitileBarView;
private TabLayout tabLayoutOrders;
private ViewPager viewpagerOrders;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_order_info2);
Intent intent = getIntent();
initView();
//设置是点击根据position进入订单选择的viewpager
int position = intent.getIntExtra("position", 0);
viewpagerOrders.setCurrentItem(position);
}
private void initView() {
//自定义的titileBar(可忽略)
ordersTitileBarView = (TitleBarView)findViewById( R.id.orders_titileBarView );
ordersTitileBarView.setTitle("我的订单");
ordersTitileBarView.setTitleBarClickListener(this);
tabLayoutOrders = (TabLayout)findViewById( R.id.tab_layout_orders );
viewpagerOrders = (ViewPager)findViewById( R.id.viewpager_orders);
//这句话是设置默认缓存viewpager,不设置默认是1,就会先缓存左右两边的viewpager,0代表不缓存,1代表缓存左右两边的Viewpager
viewpagerOrders.setOffscreenPageLimit(2);
//设置填充freagment
MyOrdersFragmentViewPagerAdapter myOrdersFragmentViewPagerAdapter = new MyOrdersFragmentViewPagerAdapter(getSupportFragmentManager(), new String[]{"全部",
"待付款", "待发货", "待收获", "退货"},this);
//设置到viewpager
viewpagerOrders.setAdapter(myOrdersFragmentViewPagerAdapter);
//关联Tablayout
tabLayoutOrders.setupWithViewPager(viewpagerOrders);
}
//这两个方法是titileBar定义接口的方法(可忽略)
@Override
public void leftClick() {
finish();
}
@Override
public void rightClick() {
}
}
上面主要的方法是:
避免viewpager的重复创建可以设置:
viewpager.setOffscreenPageLimit(2);
设置当前page左右两侧应该被保持的page数量,超过这个限制,page会被销毁重建(只是销毁视图),onDestroy-onCreateView,但不会执行onDestroy。尽量维持这个值小,特别是有复杂布局的时候,因为如果这个值很大,就会占用很多内存,如果只有3-4page的话,可以全部保持active,可以保持page切换的顺滑
这下很好理解了,默认情况下是1,所以当前fragment左右两侧,就会被保持1页pager,所以上述切换到fragment2并不会销毁任何视图,但是到fragment1,3会。这里注意这个值,是左右两侧能够维持的page,所以如果setOffscreenPageLimit(2),维持保持左右两边2个,Viewpager那么就不会频繁的销毁了.
另外,在ViewpagerFragmentAdapter中的destroyItem()方法
//super.destroyItem(container, position, object); 注释掉调用父类方法即可
取消预加载:
可以fragment的setUserVisibleHint实现,具体实现参考代码示例
setUserVisibleHint 意思就是:
fragment对用户可见,isVisibleToUser为true,不可见isVisibleToUser为false。对应于viewpager,当前pager,非当前pager
import android.support.v4.app.Fragment;
import android.widget.Toast;
/**
* Created by xiemo on 16/3/15.
*/
public abstract class BaseFragment extends Fragment {
/** Fragment当前状态是否可见 */
protected boolean isVisible;
//setUserVisibleHint adapter中的每个fragment切换的时候都会被调用,如果是切换到当前页,那么isVisibleToUser==true,否则为false
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getUserVisibleHint()) {
isVisible = true;
onVisible();
} else {
isVisible = false;
onInvisible();
}
}
/**
* 可见
*/
protected void onVisible() {
lazyLoad();
}
/**
* 不可见
*/
protected void onInvisible() {
}
/**
* 延迟加载
* 子类必须重写此方法
*/
protected abstract void lazyLoad();
}
子类的fragment:
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import net.anchong.app.R;
import net.anchong.app.adapter.MyOrderListFragmentAdapter;
import net.anchong.app.app.MyApplication;
import net.anchong.app.entity.request.model.OrderInfoRequestParam;
import net.anchong.app.entity.response.model.OrderInfoResponse;
import net.anchong.app.net.RequestUtils;
/**
* 订单的每个fragment(实现了懒加载)
* A simple {@link Fragment} subclass.
*/
public class MyOrdersFragment extends BaseFragment implements RequestUtils.OnMyOrdersListener{
private static final String TAG = "MyOrdersFragment";
private int stateId;
private ListView order_Listview;
private LinearLayout fl_empty_view;
private Context mContext;
MyOrderListFragmentAdapter myOrderListFragmentAdapter;
OrderInfoResponse.ResultDataEntity mResultDataEntity;
/** 标志位,标志已经初始化完成 */
private boolean isPrepared;
/** 是否已被加载过一次,第二次就不再去请求数据了 */
private boolean mHasLoadedOnce;
View view;
public MyOrdersFragment() {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
public static MyOrdersFragment newInstance(int stateId) {
Bundle args = new Bundle();
args.putInt("stateId",stateId);
MyOrdersFragment fragment = new MyOrdersFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_all_order, container, false);
stateId = getArguments().getInt("stateId");
initView(view);
//设置加载完成
isPrepared = true;
//开始加载
lazyLoad();
return view;
}
private void initView(View view) {
fl_empty_view = (LinearLayout)view.findViewById(R.id.fl_empty_view);//默认没有订单为显示
order_Listview = (ListView) view.findViewById(R.id.order_Listview);
myOrderListFragmentAdapter = new MyOrderListFragmentAdapter(mResultDataEntity, mContext);
order_Listview.setAdapter(myOrderListFragmentAdapter);
RequestUtils.setOnMyOrdersListener(this);
}
//获取订单的回调,返回的数据填充,可以忽略
@Override
public void getOrderInfos(OrderInfoResponse orderInfoResponse) {
mResultDataEntity = orderInfoResponse.getResultData();
if(mResultDataEntity.getTotal()!=0){
fl_empty_view.setVisibility(View.GONE);
order_Listview.setVisibility(View.VISIBLE);
myOrderListFragmentAdapter.setResultDataEntities(mResultDataEntity);
myOrderListFragmentAdapter.notifyDataSetChanged();
}
}
@Override
protected void lazyLoad() {
//这里可以实现完全懒加载,仅仅加载一次
//isPrepared是CreateView方法执行后设置为ture已经准备,isVisible(父类的)是否显示当前页面,mHasLoadedOnce是否已经加载过
//如果只设置!isPrepared || !isVisible,的话每次每个页面都会重新加载,每次只加载一个页面
//!isPrepared || !isVisible|| mHasLoadedOnce这样就完全的懒加载,每次进入只加载一次,之后不会再次加载了
if (!isPrepared || !isVisible|| mHasLoadedOnce) {
return;
}
//设置已经加载过
mHasLoadedOnce = true;
//开始请求加载
OrderInfoRequestParam orderInfoRequestParam = new OrderInfoRequestParam(stateId+"","1");
Log.e(TAG, "stateId=: "+stateId );
RequestUtils.MyOrdersListener(MyApplication.ORDERORDERINFO,orderInfoRequestParam,mContext);
}
}
ViewpagerFragmentadapter:
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;
import android.view.ViewGroup;
import net.anchong.app.fragment.MyOrdersFragment;
/**
* 我的订单
* Created by Administrator on 2016/9/1.
*/
public class MyOrdersFragmentViewPagerAdapter extends FragmentPagerAdapter /*FragmentStatePagerAdapter*/ {
private static final String TAG = "PagerAdapter";
private String[] titles;
private Context mContext;
public MyOrdersFragmentViewPagerAdapter(FragmentManager fm, String[] titles,Context context) {
super(fm);
this.titles = titles;
mContext = context;
}
public MyOrdersFragmentViewPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return MyOrdersFragment.newInstance(position);
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
@Override
public int getCount() {
return titles.length;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
Log.e(TAG, "destroyItem2" );
//如果注释这行,那么不管怎么切换,page都不会被销毁
super.destroyItem(container, position, object);
}
}
这样就实现了第一个效果
第二个效果只需要把mHasLoadedOnce去掉即可
fragmentviewpager中使用fragment(代码片段)
简书《Fragment(一)从源码角度看add和replace过程》《Fragment(二)状态改变与管理》《Fragment(三)ViewPager中使用Fragment》《Fragment(四)常见问题》CSDN《Fragment(一)从源码角度看add和replace过程》《Fragment(二)状态改变与管理》《Fragment(三)ViewPa... 查看详情
fragmentviewpager中使用fragment(代码片段)
简书《Fragment(一)从源码角度看add和replace过程》《Fragment(二)状态改变与管理》《Fragment(三)ViewPager中使用Fragment》《Fragment(四)常见问题》CSDN《Fragment(一)从源码角度看add和replace过程》《Fragment(二)状态改变与管理》《Fragment(三)ViewPa... 查看详情
fragment中tablayout加fragmentviewpager
这是要放TabLayout的Fragment<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="m 查看详情
fragmen直接来回切换deno
思路:第一步。建立一个activity。用来管理fragment。第二步‘获取fragmentManger和fragmentTraction.privateFragmentManagerfm;privateFragmentTransactionft;fm=getFragmentManager();ft=fm.beginTransaction();第三步,调用切换方法ft.replace(andro 查看详情
androidfragment
Fragment: fragment是application的用户界面或行为的一部分,Activity通过FragmentManager与fragment来交互, 获取FragementManager: Activity.getFragmentManager() and Fragment.getFragmentManager().Fragmen 查看详情
优化片段着色器
】优化片段着色器【英文标题】:OptimizeFragmentShader【发布时间】:2019-03-0401:24:05【问题描述】:我想的性能。目前我的片段着色器是fragmenthalf4fragmen_shader_texture(VertexOutTexturevIn[[stage_in]],texture2d<half>texture[[texture(0)]])constexprsampl... 查看详情
fragment延迟加载
/***Createdbyxzon2017/4/10.*/publicabstractclassBaseFragmentextendsFragment/**是否第一次显示*/privatebooleanisFirstVisible=true;/**是否第一次不显示*/privatebooleanisFirstInVisible=true;/**是否初始化*/privatebooleanisPrepared=false;@OverridepublicvoidonCreate(@... 查看详情
Android 活动组使用
...1】:如前所述,ActivityGroup已弃用。现在安卓开发者使用Fragments和Fragmen 查看详情
动态获取r.drawable.xx资源
StringimageName="index_fragmen"+getColor();finalintresId=context.getResources().getIdentifier(imageName,"drawable",context.getPackageName());if(resId!=0){Log.e("mytest","可以获取到");holder.btnCoupon.setBa 查看详情
fragment的基本应用
...请注明出处:http://blog.csdn.net/crazy1235/article/details/50933621Fragment还是先来基本介绍。Fragment–>片段。在Android3.0的时候被引入,它的出现主要是给大屏幕设备提供更加灵活的UI支持。通过对Activity布局进行分片。更加方便的对每块... 查看详情
使用androidx获取片段内的actionBar
...androidx获取片段内的actionBar【英文标题】:getactionBarinsidefragmentusingandroidx【发布时间】:2019-07-2010:35:07【问题描述】:我只想在一个带有函数的片段中获取actionBar,我正在使用Kotlin语言和AndroidX。这是我的代码:importandroidx.appcompa... 查看详情
片段选项卡未使用所有空间
】片段选项卡未使用所有空间【英文标题】:FragmentTabsnotusingallspace【发布时间】:2016-02-2712:05:52【问题描述】:我正在尝试按照本教程将我的活动应用程序转换为片段:http://www.exoguru.com/android/material-design/navigation/material-design-tab... 查看详情
fragmenttransaction的commit和commitallowingstateloss的差别
1、什么是FragmentTransaction?使用Fragment时。能够通过用户交互来运行一些动作。比方添加、移除、替换等。全部这些改变构成一个集合,这个集合被叫做一个transaction。能够调用FragmentTransaction中的方法来处理这个transaction,而且能... 查看详情
如何在android的地图中获取当前位置?
...来映射......提前致谢..这是我的地图片段..publicclassContactFragmentextendsFragmen 查看详情
如何包含由 Heat 创建的 Wix Fragments
】如何包含由Heat创建的WixFragments【英文标题】:HowtoincludeWixFragmentscreatedbyHeat【发布时间】:2010-11-1609:53:28【问题描述】:我有以下片段:<?xmlversion="1.0"encoding="utf-8"?><Wixxmlns="http://schemas.microsoft.com/wix/2006/wi"><Fragmen 查看详情
需要从寻呼机适配器识别当前视图片段
...器识别当前视图片段【英文标题】:Needtoidentifycurrentviewfragmentfrompageradapter【发布时间】:2017-05-1805:50:40【问题描述】:我们必须知道当前fragment是pageradapter中的可见模式,但无法处理。for(Fragmentfragment:getChildFragmentManager().getFragmen... 查看详情
使用 getFragmentManager().beginTransaction() 在 Android 中为 FragmentTransaction 键入不匹配
】使用getFragmentManager().beginTransaction()在Android中为FragmentTransaction键入不匹配【英文标题】:TypemismatchinAndroidforFragmentTransactionwithgetFragmentManager().beginTransaction()【发布时间】:2013-11-2119:20:39【问题描述】:当我尝试通过在活动中声... 查看详情
AsyncTask 在 ViewPager 的每个页面上运行
...evelopmenttutorial现在我想做的很简单,我在每个页面上使用Fragments。我想在每个页面上显示来自rss提要的不同内容。问题是当我转到下一个选项卡时,它会运行上一个Fragmen 查看详情