我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用。而ViewPager默认会缓存三页数据,即:Viewpager每加载一个Fragment,都会预先加载此Fragment左侧或右侧的Fragment。而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源,浪费用户流量不止,还造成卡顿,这样的结果,我们当然不会满意。那么,能不能做到当切换到这个fragment的时候,它才去初始化呢?答案就在Fragment里的setUserVisibleHint这个方法里。
该方法用于告诉系统,这个Fragment的UI是否是可见的。所以我们只需要继承Fragment并重写该方法,即可实现在fragment可见时才进行数据加载操作,即Fragment的懒加载。
代码如下:
代码如下 | 复制代码 |
packagecom.yctime.truelove.fragment;
importandroid.content.Context; importandroid.nfc.Tag; importandroid.os.Bundle; importandroid.support.annotation.Nullable; importandroid.support.v4.app.Fragment; importandroid.util.Log; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.ViewGroup;
/** * 基类Fragment */ publicabstractclassBaseFragmentextendsFragment {
protectedView mRootView; publicContext mContext; protectedbooleanisVisible; privatebooleanisPrepared; privatebooleanisFirst =true;
publicBaseFragment() { // Required empty public constructor }
@Override publicvoidsetUserVisibleHint(booleanisVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); // Log.d("TAG", "fragment->setUserVisibleHint"); if(getUserVisibleHint()) { isVisible =true; lazyLoad(); }else{ isVisible =false; onInvisible(); } }
@Override publicvoidonCreate(@NullableBundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getActivity(); setHasOptionsMenu(true); // Log.d("TAG", "fragment->onCreate"); }
@Override publicView onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if(mRootView ==null) { mRootView = initView(); } // Log.d("TAG", "fragment->onCreateView"); returnmRootView; }
@Override publicvoidonActivityCreated(@NullableBundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Log.d("TAG", "fragment->onActivityCreated"); isPrepared =true; lazyLoad(); }
protectedvoidlazyLoad() { if(!isPrepared || !isVisible || !isFirst) { return; } Log.d("TAG", getClass().getName() +"->initData()"); initData(); isFirst =false; }
//do something protectedvoidonInvisible() {
}
publicabstractView initView();
publicabstractvoidinitData();
} |
为了可复用,这里我新建了个BaseFragment,在basefragment,我增加了三个方法,一个是onVisiable,即fragment被设置为可见时调用,一个是onInvisible,即fragment被设置为不可见时调用。另外再写了一个lazyLoad的抽象方法,该方法在onVisible里面调用。
注意看这个方法:
代码如下 | 复制代码 |
protectedvoidlazyLoad() { if(!isPrepared || !isVisible || !isFirst) { return; } Log.d("TAG", getClass().getName() +"->initData()"); initData(); isFirst =false; } |
这里我们做了三个判断,判断isPrepared和isVisible和isFirst只有全为true,才去执行initData()方法加载网络(或本地)数据。
①isPrepared参数在系统调用onActivityCreated时设置为true,这时onCreateView方法已调用完毕(一般我们在这方法里执行findviewbyid等方法),确保 initData()方法不会报空指针异常。
②isVisible参数在fragment可见时通过系统回调setUserVisibileHint方法设置为true,不可见时为false,这是fragment实现懒加载的关键。
③isFirst确保ViewPager来回切换时BaseFragment的initData方法不会被重复调用,initData在该Fragment的整个生命周期只调用一次,第一次调用initData()方法后马上执行 isFirst = false。
本篇文章为大家介绍了Android Studio获取SHA1值实例详解的相关资料,有需要的朋友可以参考一下。Android Studio获取SHA1值实例详解
前言
使用百度地图的小伙伴们都会知道获取百度地图的密钥需要SHA1和包名,在Eclipse中,我们可以很方便的得知SHA1值,如下图:
但是在Android Studio中,该怎么获取SHA1的值呢?不要着急,马上呈上~
Android Studio获取SHA1值
强大的Android Studio为我们提供了Terminal这个工具,我们可以通过他进行相应命令从而获取所需内容。
Java中提供了Keytool工具去让我们管理证书,那么接下来我们将通过他获取我们所需要的SHA1值。
使用命令如下:
代码如下 | 复制代码 |
keytool -list -v -keystore 证书地址 PS:如果需要获取debug版本的证书,按如下例子查找即可 keytool -list -v -keystore C:\Users\HLQ\ .android\debug.keystore 默认密码为:android |
关于证书地址,给大家举个例子,例如LZ证书直接在桌面,那么我们就可以按下面这么写:
代码如下 | 复制代码 |
C:\Users\HLQ\Desktop\hlq_test.jks |
具体实践如下:
2017年6月2日23:16:33更新如下内容:
突然想起赵小贱某天贱兮兮的告诉我,还有一种非常快捷可以查看debug的sha1值,感觉很方便,下面截图为大家奉上,稍后会跟随相关步骤~
1.运行你的demo,点击AS展开右侧Gradle功能区;
2.点击项目名,点击Tasks,点击android,用力双击signingReport,在下方Run区域查看自己想要的东西~
原文链接:http://blog.csdn.net/u012400885/article/details/68945498
本文介绍了Android Studio中引入Lambda表达式的方法,非常实用,有兴趣的同学快来看看吧
方法如下:
依次点击 【File】【Other Settings】【Default Project Structure】确保当前项目使用的JDK版本是1.8。
打开项目(Project)的build.gradle,在dependencies节点添加
classpath 'me.tatarka:gradle-retrolambda:3.2.0' |
打开项目(Module)的build.gradle,在根节点添加
代码如下 | 复制代码 |
apply plugin: 'me.tatarka.retrolambda' |
在android节点增加
代码如下 | 复制代码 |
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } |
最后对比下使用 Lambda表达式前后代码的变化
本文介绍了Android实现图片拖动效果的教程,非常实用,有兴趣的同学快来看看吧要求:
1.通过手指移动来拖动图片
2.控制图片不能超出屏幕显示区域
技术点:
1.MotionEvent处理
2.对View进行动态定位(layout)
activity_main.xml:
代码如下 | 复制代码 |
<RelativeLayoutxmlns: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"> <ImageView android:id="@+id/iv_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/test"/> </RelativeLayout> |
MainActivity:
代码如下 | 复制代码 |
publicclassMainActivityextendsActivityimplementsOnTouchListener { privateImageView iv_main; privateRelativeLayout parentView; @Override protectedvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv_main = (ImageView) findViewById(R.id.iv_main); parentView = (RelativeLayout) iv_main.getParent(); /* int right = parentView.getRight(); //0 int bottom = parentView.getBottom(); //0 Toast.makeText(this, right+"---"+bottom, 1).show(); */ //设置touch监听 iv_main.setOnTouchListener(this); } privateintlastX; privateintlastY; privateintmaxRight; privateintmaxBottom; @Override publicbooleanonTouch(View v, MotionEvent event) { //得到事件的坐标 inteventX = (int) event.getRawX(); inteventY = (int) event.getRawY(); switch(event.getAction()) { caseMotionEvent.ACTION_DOWN: //得到父视图的right/bottom if(maxRight==0) {//保证只赋一次值 maxRight = parentView.getRight(); maxBottom = parentView.getBottom(); } //第一次记录lastX/lastY lastX =eventX; lastY = eventY; break; caseMotionEvent.ACTION_MOVE: //计算事件的偏移 intdx = eventX-lastX; intdy = eventY-lastY; //根据事件的偏移来移动imageView intleft = iv_main.getLeft()+dx; inttop = iv_main.getTop()+dy; intright = iv_main.getRight()+dx; intbottom = iv_main.getBottom()+dy; //限制left >=0 if(left<0) { right += -left; left =0; } //限制top if(top<0) { bottom += -top; top =0; } //限制right <=maxRight if(right>maxRight) { left -= right-maxRight; right = maxRight; } //限制bottom <=maxBottom if(bottom>maxBottom) { top -= bottom-maxBottom; bottom = maxBottom; } iv_main.layout(left, top, right, bottom); //再次记录lastX/lastY lastX = eventX; lastY = eventY; break; default: break; } returntrue;//所有的motionEvent都交给imageView处理 } } |