美文网首页
Android小知识汇总

Android小知识汇总

作者: 青果果 | 来源:发表于2017-11-29 10:09 被阅读0次

1.ScrollView相关

问题1.有ScrollView的布局,进入页面时会自动滑动

在ScrollView父布局写 android:focusableInTouchMode="true"

参考:从源码剖析原理及解决方式

问题2.ScrollView和ListView嵌套

http://blog.csdn.net/insist_onzw/article/details/74857925
http://blog.csdn.net/liaoinstan/article/details/50509122

ListView源码onMeasure()方法中
ListView的父容器测量模式为UNSPECIFIED的时候
ListView的高度默认为一个item的高度

//ListView的父容器测量模式为UNSPECIFIED的时候,ListView的高度默认为一个item的高度
//代码是源码其中一部分,有省略
if (heightMode == MeasureSpec.UNSPECIFIED) {
    heightSize = mListPadding.top + mListPadding.bottom + childHeight +
                   getVerticalFadingEdgeLength() * 2;
}

那我们再看看ScrollView源码里面是什么样的

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        if (!mFillViewport) {//源码debug这里会直接return
            return;
        }
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.UNSPECIFIED) {
            return;
        }
}

那继续看SrcollView的父类FrameLayout的onMeasure做了什么

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int count = getChildCount();

        final boolean measureMatchParentChildren =
                MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY ||
                MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY;
        mMatchParentChildren.clear();

        int maxHeight = 0;
        int maxWidth = 0;
        int childState = 0;

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (mMeasureAllChildren || child.getVisibility() != GONE) {
                measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);//这个方法
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                maxWidth = Math.max(maxWidth,
                        child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
                maxHeight = Math.max(maxHeight,
                        child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
                childState = combineMeasuredStates(childState, child.getMeasuredState());
                if (measureMatchParentChildren) {
                    if (lp.width == LayoutParams.MATCH_PARENT ||
                            lp.height == LayoutParams.MATCH_PARENT) {
                        mMatchParentChildren.add(child);
                    }
                }
            }
        }

ScrollView有重写这个方法measureChildWithMargins()
可看到ScrollView给子类的测量MODE都是UNSPECIFIED
所以ScrollView嵌套ListView的时候只会显示一个item

 @Override
    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
            int parentHeightMeasureSpec, int heightUsed) {
        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                        + widthUsed, lp.width);
        final int usedTotal = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin +
                heightUsed;
        final int childHeightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
                Math.max(0, MeasureSpec.getSize(parentHeightMeasureSpec) - usedTotal),
                MeasureSpec.UNSPECIFIED);//重点来了,看到了给子类的测量MODE都是UNSPECIFIED

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

那么ScrollView嵌套LinearLayout再嵌套ListView
看看LinearLayout源码竖直方向布局的时候 测量方法

void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
       
                // Determine how big this child would like to be. If this or
                // previous children have given a weight, then we allow it to
                // use all available space (and we will shrink things later
                // if needed).
 final int usedHeight = totalWeight == 0 ? mTotalLength : 0;
measureChildBeforeLayout(child, i, widthMeasureSpec, 0,heightMeasureSpec, usedHeight);

 void measureChildBeforeLayout(View child, int childIndex,
            int widthMeasureSpec, int totalWidth, int heightMeasureSpec,
            int totalHeight) {
        measureChildWithMargins(child, widthMeasureSpec, totalWidth,
                heightMeasureSpec, totalHeight);
    }

//LinearLayout并没有重写ViewGroup的方法measureChildWithMargins
  protected void measureChildWithMargins(View child,
            int parentWidthMeasureSpec, int widthUsed,
            int parentHeightMeasureSpec, int heightUsed) {
        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                        + widthUsed, lp.width);
        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                        + heightUsed, lp.height);

        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

ViewGroup的getChildMeasureSpec方法
public static int getChildMeasureSpec(int spec, int padding, int childDimension) {
case MeasureSpec.UNSPECIFIED:
            if (childDimension >= 0) {
                // Child wants a specific size... let him have it
                resultSize = childDimension;
                resultMode = MeasureSpec.EXACTLY;
            } else if (childDimension == LayoutParams.MATCH_PARENT) {
                // Child wants to be our size... find out how big it should
                // be
                resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
                resultMode = MeasureSpec.UNSPECIFIED;
            } else if (childDimension == LayoutParams.WRAP_CONTENT) {
                // Child wants to determine its own size.... find out how
                // big it should be
                resultSize = View.sUseZeroUnspecifiedMeasureSpec ? 0 : size;
                resultMode = MeasureSpec.UNSPECIFIED;
            }

2.TextView相关

一些比较少用的属性

1、android:lineSpacingExtra //设置行间距,如”8dp”
2、android:lineSpacingMultiplier //设置行间距的倍数,如”1.5″
3、android:ellipsize="end"//文字省略

3.RatingBar相关

问题1:要显示半颗星,必须设置secondaryProgress

    <item
        android:id="@+android:id/progress"
        android:drawable="@drawable/evaluate_ratingbar_s">
    </item>

    <item
        android:id="@+android:id/secondaryProgress"
        android:drawable="@drawable/evaluate_ratingbar_half">
    </item>

android:numStars="5" //星星总数
android:rating="3.5" //默认值设置星星个数
android:stepSize="0.5"//步进值

4.PopupWindow相关

问题1:Android7.0显示 PopupWindow位置错误

用showAsDropDown()这个方法,让pop显示在某个View的下面,而且pop的高度是match_parent的话,其显示的位置在Android7.0以下系统正常,在7.0和7.1系统显示不正常,会全屏显示盖着整个页面

问题2:PopupWindow需要设置背景点击外部才消失

在6.0以下 需要设置背景点击外部才消失,6.0以后不需要设置

setBackgroundDrawable(Drawable background)

参考:
从源码剖析PopupWindow 兼容Android 6.0以上版本点击外部不消失
不得不吐槽的Android PopupWindow的几个痛点
PopupWindow 点击外部和返回键无法消失背后的真相

5.ListView相关

问题1.ListView和ScrollView嵌套

问题2.ListView去掉点击水波纹效果,只展示数据

有时候可能listview只是展示数据而已,item并不需要响应点击,也不需要点击效果
那么就可以给listview设置属性

android:listSelector="@android:color/transparent"

6.空格替代符

名称 编号 描述
&nbsp; &#160; 不会被合并的空格,长度与常规空格相同
&ensp; &#8194; 全角空格,长度等于半个中文字符
&emsp; &#8195; 全角空格,长度等于一个中文字符

开发中可能会遇到要用空格对齐文字
密  码,中间有连续空格的,在资源文件中不管打多少个空格都只会显示一个空格

可使用空格的替代符号
替代符号就是在需要显示空格的地方加入替代符号,这些符号会被浏览器解释为空格显示。
“新 密 码”在资源文件中应该这样写的:新&#8194;密&#8194;码
“密  码”在资源文件中应该这样写的:密&#8195;&#8195;码

首行空两格可以在java代码用: \u3000\u3000
表示的是: 中文(全角)空格
解释:\uxxxx
其中xxxx表示一个16进制数字 这种格式是unicode码的写法表示一个char字符

那就顺便再讲下占位符的使用
有时候我们需要动态修改Android中strings.xml文件中的值
strings.xml中节点是支持占位符的,如下所示:
<string name="name">整数型:%1$d,浮点型:%2$.2f,字符串:%3$s</string>
%后面是占位符的位置,从1开始(比如这里用到了三个占位符,从1开始往后排)
$ 后面是填充数据的类型
%d:表示整数型;
%f :表示浮点型,其中f前面的.2表示小数的位数
%s:表示字符串

代码实现:

//XML 文件中这样写
 <string name="book">书名:《%1$s》,作者:%2$s,编号(整数):%3$d,价格(浮点):%4$.2f元</string> 
//代码中这样设置,需要一 一 对应
textview.setText(String.format(getResources().getString(R.string.book),"金瓶梅", "西门庆", 2249, 88.3f));

7.JNI是什么?

Android系统的底层库是由c/c++编写,上层Android应用程序和应用程序框架通过JNI(JavaNative Interface)调用底层接口.

Android使用JNI开发分两种情况:一是使用已经编译好的.so动态库;二是使用c/c++源代码开发.

一些第三方的库出于性能或代码安全的目的,会将核心代码用C/C++来实现,然后提供编译好的so文件或jar包给我们.

so文件是什么?

Android中用到的so文件是一个c++的函数库,apk或jar包中调用so文件时,需要将对应so文件打包进apk或jar包.

如何加载so文件?**

假设你的so文件为:libBaiduMapSDK_v350_1.so

这样加载:

String libName = "BaiduMapSDK_v350_1"; // 注意:库名libName, 没有前缀lib和后缀.so

System.loadLibrary( libName ); //在使用前一定要先加载

so文件应该放在哪里?

在Eclipse中我们将so文件放到libs目录下就可以了, 那么在AndroidStudio中应该将so文件放到哪里呢?

放到moduleName/src/main/jniLibs目录下,如果没有jinLibs目录就新建一个.

armeabi、armeabi-v7a、mips、x86这四个文件夹是干嘛的呢?

表示四种不同的cpu类型,不同的cpu的特性不一样,在使用so文件时注意区分.

可以直接复制so文件粘贴到对应的文件夹下

ok之后so文件就进来啦.

相关文章

  • Android 小知识汇总

    Import project from external model和Create project from ex...

  • Android小知识汇总

    1.ScrollView相关 问题1.有ScrollView的布局,进入页面时会自动滑动 在ScrollView父...

  • Android面试题汇总

    面试题汇总 Android复习资料——Android知识点汇总(一) 史上最全的Android面试题集锦 ForA...

  • 我的Android知识体系

    热门博客 Android知识体系汇总Gityuan数据结构与算法互联网公司Android面试题汇总隔壁老李头 23...

  • 开源项目聚合

    Android-Tips,超级全的知识,字母索引 Android 开源项目分类汇总1,awesome-androi...

  • Android开发中小问题汇总三

    【Android开发中小问题汇总目录】【Android开发中小问题汇总一】【Android开发中小问题汇总二】 A...

  • 换肤框架Android-Skin-Support解析

    知识点汇总: 一:换肤框架Android-Skin-Support项目概述 二:实现换肤功能背景知识点学习 三:对...

  • 小知识汇总

    视图网,fotomore,alamy,istock等等。比如视图网为世界各地的商业和个人提供用于各种不同项目用途的...

  • 小知识汇总

    查看一个变量名是不是存在 直接输入的话会提示错误,可以挂到window上以对象的方式查看 JS获取尺寸 cli...

  • Android基础知识汇总

    PS:以记笔记的方式,汇总一些android基础知识。 1、android 四种启动模式 2、activity或f...

网友评论

      本文标题:Android小知识汇总

      本文链接:https://www.haomeiwen.com/subject/jsqubxtx.html