Android小知识汇总

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文件就进来啦.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容