Android FragmentManager使用

Android FragmentManager使用

1.获取fragmentManager

要想使用好fragmentmanager,第一步肯定先要正确获取他呀:

  • 获取activity中的fragmentmanager:在activity中 getFragmentManager()getSupportFragmentManager()(这个用于support包的fragment,向下兼容,现api28后变成support包全部转为Androidx)如果在fragment中则可以先getactivity()获取到其依赖的activity
  • 获取在fragment中的fragmentmanager:getChildFragmentManager()这种情况用于fragment中嵌套fragment,同时子fragment可以通过getParentFragment()获得

2.事务

  • 在Android中fragmentManager是以事务为单位来管理的,每次我们都通过fragmentManager.beginTransaction()来获得一个FragmentTransaction对象,然后进行添加,替换,删除等,最后commit提交,这整个过程从begin到commit进行的所有操作就是一个事务,每个commit提交一个事务
  • 这里要注意commit调用commit()方法并不立即执行这个事务,而是在Activity的UI线程之上(”main”线程)调度运行,以便这个线程能够尽快执行这个事务,这意味这个commit是异步的,所以必要时可以通过commitNow()来立即执行

2.fragmentManager的各种方法

  • add()add方法会直接将一个fragment添加到指定的id布局中,不管这个布局容器中原来有没有,无条件覆盖。所以会叠加,而之前的fragment只是被遮挡,view并不会被摧毁
  • getFragmentbyTag()getFragmentbyId()这两个方法可以获得有相应的tag或id属性的fragment(这两个属性也可以通过xml里布局设置),那么就出现了有多个fragment拥有相同的tag和id,那调用该方法获得的是哪个呢?实测获得的是最顶层的那个fragment,也就是最近添加的
  • replace()该方法不同于add()可有其注释的出,relplace()会先相应调用该布局id容器中中所有的add的fragment的remove()方法,然后在调用add()方法
  • remove()移除这个fragment,最后会调用onDetach()
  • show()hide() ,这里要注意调用这两个方法并不会走fragment的生命周期,which means 并不会调用onPause()onStop方法,而是只调用了onHiddenChanged()方法,所有改变应在这个方法里,重写之
  • addToBackTrack()最后说一下fragment的回退栈,注意,只有在commit事务是调用了addToBackTrack()方法,才会有回退栈,才会在回退栈里添加,否则就没有回退栈,pop方法不会有任何改变。 addToBackTrack()即把本次事务的所有操作储存起来,注意调用了addtobaktrack后remove方法不会真的把fragment移除,而只是distroy了它的view,并没有调用onDetach(),也就是说它还连接在宿主中。
  • popbackTrack,该方法即将回退栈中的最近的一次事务pop出来,也就是反过来调用方法,add就是remove,remove就add,所以如果这个调用了replace,那么pop后就会将这个replace add的fragment移除,然后在把之前remove的所有fragment add到里面。而之前就存在的fragment依然存在,没有变化,就像是add覆盖到上面一样。所以加入回退栈后pop可以回到上次操作

最后,fragment在现在开发中已经十分常用,所以必须完全理解他的生命周期和fragmentManager如何管理它,这样才能高效的复用,利用fragment

Android构建工具各种版本

Android构建工具各种版本

minSdkVersion <= targetSdkVersion <= compileSdkVersion

minSdkversion:

  • 作用:告诉应用市场安装该应用的最低版本,也表示了在编程中你必须保证所有的方法的最低sdk都需要大于该值,否则Androidstudio会提醒你添加sdk判断

compilesdkversion:

  • 作用:告诉 Gradle 用哪个 Android SDK 版本编译你的应用。使用任何新添加的 API 就需要使用对应 Level 的 Android SDK。

    targetsdkversion

    这个是比较难于理解的值了
  • 作用:主要是为了Android系统的向前兼容,targetSdkVersion 所暗示的许多行为变化都记录在 VERSION_CODES 文档中,所以当出现更新了新系统时,如果新系统版本大于了该应用的targetsdkversion版本,就不会在该应用使用最新的变化,

    targetSdkVersion 是 Android 提供向前兼容的主要依据,在应用的 targetSdkVersion 没有更新之前系统不会应用最新的行为变化

  • 举个例子,比如:Google表示,为保证用户数据和设备的安全,针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输,需要使用下一代(Transport Layer Security)传输层安全协议,而 Android Nougat 和 Oreo 则不受影响。
    所以当实机的Android版本大于27,使用http请求报错时就会not permitted by network security policy,如何解决呢?
    那么这时,我们就可以利用targetsdkversion,将其设置为27,那么,当app运行在sdk28(大于27)的真机上时,他就不会去使用这条限制(不能使用http),而是使用sdk 27的规则,(当然这也限制了你不能使用其他sdk 28的新功能)。
  • 所以targetsdkversion的含义就是:我的这个app的目标sdk就是 27,我已经完全测试好了,跑在sdk27上没有一点问题,如果你的版本大于27,那就请先使用27的sdk,先不要使用你的高版本sdk,否则有些地方就可能出错。等我什么时候适配好了,我将sdk改为了28,那么你才能使用最新的sdk功能。

buildtoolversion

-作用:表示构建工具的版本,其中包括了打包工具aapt、dx等等,所以应该大于compile版本

正则表达式(Java)

正则表达式(Java)


JAVA中的反斜杠 \:

注意: 在java中反斜杠 \ 本身具有特殊含义,表转义字符,所以要想打出 \ 就需要\\(很多语言都是这样)
所以,作为转义字符,有\n表换行 …
要想输入\,就需要\\, System.out.print("\\")—–> \

常用的正则表达符号

  1. . 匹配所有单个字符
  2. \ 反斜杠,将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,”n”匹配字符”n”。”\n”匹配换行符。序列”\\“匹配”\“,”\(“匹配”(“
  3. ^ $分别表示从开始位置匹配和结尾位置匹配
  4. * 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配”z”和”zoo”
  5. +一次或多次匹配前面的字符或子表达式
  6. ?零或一次匹配前面~~
  7. {n}表示正好匹配n次,{n,}表示至少匹配n次,{n,m}表示匹配 >=n,<=m
  8. (regex):括号表示捕获所匹配的字符串
  9. [xyz]:方括号表示字符集,匹配匹配包含的任一字符[^xyz]反向字符集
  10. [a-z] 表示所有小写字母
  11. \b匹配一个字边界,即字与空格间的位置,如”er\b”匹配”never”中的”er”,但不匹配”verb”中的”er”。
  12. \d表示数字,等效[0-9]   \D非数字
  13. \s匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。S非空格
  14. \w匹配任何字类字符,包括下划线。与”[A-Za-z0-9_]”等效。

Pattern 与Matcher类

使用;pattern 用其静态方法compile(regex) 创建,有split等方法
matcher可以用pattern.matcher(String)来创建,有matches相关,捕获方法
注意

  • find()方法是部分匹配,是查找输入串中与模式匹配的子串,如果该匹配的串有组还可以使用group()函数。

  • matches()是全部匹配,是将整个输入串与模式匹配,如果要验证一个输入的数据是否为数字类型或其他类型,一般要用matches()。

  • 必须先match.find(),然后才会捕获匹配,然后match.group()获取find结果,
    可以while(match.find())来一直搜索所有匹配到的

分组

从正则表达式左侧开始,每出现一个左括号“(”记做一个分组,分组编号从1开始。0代表整个表达式。

主要用于matcher.find(),,, matcher.group(index)
group(0)特指所匹配到的整个字符串,不计入group的length

android 中图片单位及图片加载优化相关知识

android 中图片单位及图片加载优化相关知识


1. 图片相关知识,像素,分辨率

px就是图片中最小的点,最小单位,单位色块,每个图都是由这些小像素点组成的,如基本的图片格式bitmap,注意像素的大小没有固定的长度,不同设备上一个单位的像素色块的大小是不一样的
分辨率=画面水平方向的像素值 * 画面垂直方向的像素值。
分辨率可以分为两方面:屏幕分辨率和图像分辨率。
屏幕分辨率如1024*768,就表示设备水平方向上有1024个像素点,垂直方向上有768个
图片分辨率也如上所说,比如如果某图片是500*200,就表示如果这个图片一比一显示的话,就是水平方向有500个像素点,而垂直方向有200个.
而像素点的大小不一样,所以同一张分辨率的图片在不同尺寸的显示器上很可能显示不同大小,或者即便尺寸相同,分辨率高的那个图片显示会小
像素越高,单个面积越小,显示的画质就越细致(当然要有相应分辨率的图片)

补充:图片的放大缩小:
放大是通过算法认为插入很多像素,所以如果放的很大,有效像素就很少,就会变得模糊
缩小是通过一定的算法删去一部分像素,所以会在细节上对视一小部分像素

所以如果图像分辨率小于显示器分辨率时,第一种是显示实际大小,但不是全屏,第二种是放大来全屏显示
如果大于显示器分辨率,第一种是局部显示(全屏),可拖放,第二种是通过缩小全屏显示

finally,虽然不同设备上像素块大小会不一样,但是同一台硬件设备上的屏幕分辨率、像素块大小是不会变的。PC电脑上之所以可以调整屏幕分辨率,其实也是通过算法转换了

1.android 图片,控件大小相关单位

  • px:
    (Pixel像素)构成图像的基本单元,但是单个像素的大小不固定,所以在不同尺寸设备上会有拉伸缩放,不推荐
  • dpi:
    是指屏幕上每英寸距离中有多少个像素点,dpi=dpi=√hight^2+width^2 / size (android以160dpi为标准)
  • dp(dip) 设备独立像素 device independent pixel
    一般都用这个作单位,顾名思义,独立,对于相同尺寸的手机,即使分辨率不同,同DP的组件占用屏幕比例相同,UI效果也相同。(注意,是相同的尺寸) dp可以维护Android组件自身的比例平衡,不至于在不同屏幕上变形
    转换公式:px = dp * (dpi/160)
  • sp
    主要用于字体,使得字体可以根据用户手机设置来修改字体大小

注:如今的dpi不能根据物理计算,是厂家生产时写在系统配置中的固定数值,为了简化屏幕适配,一般机型的dpi的取值会参考上面的范围,但是总会有一些特殊的机型就是不采纳官方的建议

可通过:dpi可以通过DisplayMetrics类的densityDpi属性获取当前手机的dpi数值,该类也可以获取到跟屏幕密度有关的其它属性。一般获取DisplayMetrics类有以下方法:

1
2
3
4
5
6
7
8
方式1:
//content:Activity,Content,Application.
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
方式2:
//getSystemService可以通过 Activity,Content,Application等获取.
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(displayMetrics);

屏幕适配

主流推荐今日头条适配方案但自己不是太懂。。。

  • 使用wrap_content、match_parent、weight
  • 使用相对布局

几个不同文件夹放的本地图片drawable

Bitmap.decodeResource() 源码,新图的高度 = 原图高度 * (设备的 dpi / 目录对应的 dpi )

bitmap

Bitmap 就是Android中的图片,一张位图,只有生成了bitmap,才占内存,可以通过bitmap.getbytecount()来获取该bitmap具体占用内存

  • bitmap的创建:

    1. 通过已有的bitmap创建(可以对已有的bitmap进行各种操作放大,裁剪等):
      createBitmap(...)
      createScaleBitmap(...)
    2. 通过BitmapFactory,从各种数据源来解析,创建bitma对象:
      • decodeByteArray(byte[] data, int offset, int length):从指定的字节数组的offset位置开始,将长度为length的字节数据解析成Bitmap对象。
      • decodeFile(String pathName):从pathName指定的文件中解析、创建Bitmap对象。
      • decodeFileDescriptor(FileDescriptor fd):从FileDescriptor对应的文件中解析、创建Bitmap对象。
      • decodeResource(Resources res, int id):根据给定的资源ID从指定资源中解析、创建Bitmap对象。
      • decodeStream(InputStream is):从指定的输入流中解析、创建Bitmap对象。
  • BitmapFactory.Options

    1. BitmapFactory.Options类是BitmapFactory对图片进行解码时使用的一个配置参数类,其中定义了一系列的public成员变量,每个成员变量代表一个配置参数。
    2. inperferredConfig参数,设置图片使用的颜色模式
    3. inJustDecodeBounds,true—>告诉BitmapFactory只是获得长宽,不用加载bitmap到内存中,返回null
    4. inSmapleSize 尺寸压缩,减少图片水平竖直像素点(分辨率)只能缩小,且为2的倍数,(<1时自动变为1)
  • Matrix

    1. matrix类,即矩阵,可以对图片bitmap矩阵进行一些列线性变换,放大,旋转,位移等等

图片的三层缓存

加载图片时,应一次从内存—>本地—>网络去寻找图片资源,并以图片的url值为key

  1. 从内存获取:使用的是LruCache这个类(Least Recently Used )即最近最少使用算法,内部维护一个LinkedHashMap
  2. 从文件获取:google推荐的DiskLruCache,硬盘缓存类
  3. 网络
  4. 在上传,缓存本地时最好压缩一下,insamplesize尺寸压缩和compress质量压缩,以减小文件大小

加载网络大图,多图优化

加载大图,长图时,可以用BitmapRegionDecoder进行图片的局部加载

参考:
google-androld
csdn1
zhihu

c++坑之拷贝函数总结

C++构造函数


  1. c++类的中有两个特殊的构造函数(都是构造函数)
    (1)无参构造函数
    (2)拷贝构造函数classname (const classname &obj)(默认的拷贝构造函数—常引用型,拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量)

  2. 它们的特殊之处在于:
    (1)当类中没有定义任何构造函数时,编译器会默认提供一个无参构造函数且其函数体为空;
    (2)当类中没有定义拷贝构造函数时,编译器会默认提供一个拷贝构造函数,进行成员变量之间的拷贝。(这个拷贝操作是浅拷贝)

注意:也就是说,构造函数包含拷贝函数,如果定义了一个拷贝函数,就没有默认的构造函数了

拷贝函数的使用时机

当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:

  • 一个对象以值传递的方式传入函数体
  • 一个对象以值传递的方式从函数返回
  • 一个对象需要通过另外一个对象进行初始化
  • c++STL容器也是调用拷贝构造函数

深拷贝和浅拷贝

1.深拷贝是为指针分配了地址(比如为其new了一个新的)而浅拷贝只是赋值---pr1=pr2,此时浅拷贝两个的对象的某个属性的指针指向同一块地址。(图:浅拷贝,深拷贝)
浅拷贝
深拷贝

深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝

等号运算符与拷贝函数

1
2
3
4
5
6
7
如果对象在申明的同时马上进行的初始化操作,则称之为拷贝运算。例如:
class1 A("af"); class1 B=A;
此时其实际调用的是B(A)这样的浅拷贝操作。
如果对象在申明之后,在进行的赋值运算,我们称之为赋值运算。例如:
class1 A("af"); class1 B;
B=A;
此时实际调用的类的缺省赋值函数B.operator=(A);

等号运算符类似浅拷贝,所以,class有指针,不仅一定要重写拷贝构造函数(写深拷贝),还要重载=运算符8

##NOTE

  1. 尽量避免值传递,最好用指针和引用.如果对象有内部指针指向动态分配的堆内存,丝毫不要考虑把对象按值传递给函数,要按引用传递。并记住:若函数不能改变参数对象的状态和目标对象的状态,则要使用const修饰符
  2. 对于类的成员需要动态申请堆空间的类的对象,大家都知道,我们都最好要overload其赋值函数和拷贝函数。拷贝构造函数是没有任何返回类型的,这点毋庸置疑。 而赋值函数可以返回多种类型,例如以上讲的void,类本身class1,以及类的引用 class & (可以实现连等)

参考两篇很好的博客博客2

gradle

常用的Gradle命令 查看版本号: gradle -v 编译执行某个task: gradle Task名 静默编译执行某个task: gradle -q Task名(q表示quiet模式,表示编译执行Gradle脚本的过程中,只输出必要的信息. 除了quiet模式外,Gradle中还有其他三种模式) 编译执行某个Project中的某个task:gradle -b Project名 Task名(Gradle默认只执行- - - build.gradle文件中,自定义其他文件xxx.gradle编译运行显式指定Project名称,这里的build.gradle其实表示的就是build Project) 显示所有的Project:gradle projects 显示所有的task:gra...

Continue Reading →

了解 Linux + Zsh + GCC + GDB + Vim/Emacs 环境

1.Linux为什么我们要用或必须用linux???!!! free software不仅是因为他是免费的,他更是开源的,是真正自由的你知道自己到底要做什么,想怎么做,不需要有人来强制你安装一些东西,完全控制你的电脑,甚至是私人订制,DIY你的电脑 我觉得linux对我们来说,最重要的就是安装一些软件十分方便,配置环境更是几行命令的事,他带了很多高效的工具,比如git,vim,gdb等等,可以在终端(写一写shell脚本)实现一切操作…可能你们现在没太感觉到,但等你熟练以后,一定会发现他的好处的!而且,这个系统上没有游戏,等一些乱七八糟的软件,这会一定程度上阻止你开小差。。。所以,总的来说,linux真的是一个十分高效的,更适合程序员的操作系统。还有一个重要原因是,我们软件工程师...

Continue Reading →

Machine Learning

课程---吴恩达老师学习路线本来准备边看视频边看周志华大佬的西瓜书,结果第三章看完就给跪了,全是数学公式,总之,在没有把数学基础打好之前还是先别看这本书了(数学学习参考上面的学习路线,主要是微积分,概统,线性代数矩阵)否则完全看不懂的...相反视频里的是相对简单的,还有专门介绍线性代数的课程可以先看这个入门,然后再继续西瓜书 第一周课程内容 基础名词 回归与分类 监督与不监督学习  我们的目标是,在给定训练集的情况下,学习函数h:X→Y,使得h(x)是y的对应值的“好”预测器 假设函数 方法线性回归1.cost function使用代价函数来衡量假设函数的准确性房价预测(线性回归问题):choose i0,i1 so that h(x)is close to y for our...

Continue Reading →

© 2020 WPY's Android Tour All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero