Android各种小技巧(持续更新)

  本文主要记录博主在平日工作中遇到的各种困惑,以及对应的解决方案。

ScrollView嵌套Listview时引起冲突的解决办法

  通常情况下,不建议两个或以上带滚动功能的控件嵌套使用。解决此问题的一种常用方法是手动设定ListView的高度为所有子项的总高度。

    /**
     * 重新计算ListView的高度
     */
    public void calcListViewHeight()
    {
        int totalHeight = 0;
        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.UNSPECIFIED);
        View view = null;

        for (int i = 0; i < adapter.getCount(); i++)
        {
            view = adapter.getView(i, view, listview);
            if (i == 0)
            {
                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
            }
            view.measure(View.MeasureSpec.makeMeasureSpec(desiredWidth, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));// 计算子项View 的宽高

            totalHeight += view.getMeasuredHeight(); // 统计所有子项的总高度
        }

        ViewGroup.LayoutParams params = listview.getLayoutParams();
        params.height = totalHeight+ (listview.getDividerHeight() * (listview.getCount() - 1) );
        listview.setLayoutParams(params);

        //显示定位到顶部(因为设定后,焦点会转移到listview上)
        globalLayout.setFocusable(true);
        globalLayout.setFocusableInTouchMode(true);
        globalLayout.requestFocus();
    }

这里要求ListView中的每个Item必须是LinearLayout布局,因为其他的Layout都没有重写onMeasure()方法,所以会在调用measure()时抛出异常。


在onCreate()中无法得到自适应的测量宽度和测量高度的解决办法

  使用getMeasuredWidth()和getMeasuredHeight()获取控件和布局的测量高度和测量宽度需要在它们自身调用onMeasure()之后。在Activity中的onCreate()方法进行时,是无法拿到自适应宽高控件的测量宽度和测量高度的。可通过加回调的方法获取,代码如下。

//这里当layout发生布局改变时,测量convertView的高度(这段代码源自一个ViewHolder,因此两者是同一个布局)
layout.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                int height = convertView.getMeasuredHeight();
                ViewGroup.LayoutParams lps = linePostfix.getLayoutParams();
                lps.height = height;
                linePostfix.setLayoutParams(lps);
            }
        });

设置光标显示时,EditText是否弹出软键盘

  在一些IM软件中,有时需要在EditText显示输入光标时,软键盘不弹出(比如在输入颜文字的情况下,打开表情布局即可)。TextView类中有一个名为setShowSoftInputOnFocus的方法,可以设置软键盘在获得焦点时是否弹出,但这个方法在API21时才开放为公有的。在API21之前,需要使用反射来调用这个函数,代码如下。

    /**
     * 设置光标显示时,Edittext是否弹出软件盘,
     */
    private void setEnableShowSoftInput(boolean enable) 
    {
        Class<EditText> cls = EditText.class;
        Method method;
        try 
        {
            method = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
            method.setAccessible(true);
            method.invoke(editMsg, enable);  //editMsg为EditText控件实例
        } 
        catch (Exception e) {}
    }

在StringBuilder中使用HTML格式

  显示在TextView中的文本,如果希望不同部分显示不同的颜色或者不同的字号的话,使用Html类中的fromHtml静态方法是个不错的选择。不过对于字符串比较长的情况,我们通常会先使用StringBuilder来构建这个字符串,但是StringBuilder并不能渲染Html格式,需要使用SpannableStringBuilder这个类代替StringBuilder来构建字符串。代码如下:

TextView txt = (TextView) findViewById(R.id.txt_test);
        SpannableStringBuilder sb = new SpannableStringBuilder();
        sb.append("你今天已经吃了").append(Html.fromHtml("<font color=#000080>"+"20"+"</font>")).append("斤米饭")
            .append(",和").append(Html.fromHtml("<font color=#800000>" + "10" + "</font>")).append("斤肉")
            .append(",外加").append(Html.fromHtml("<font color=#008000>" + "15" + "</font>")).append("斤水果");
        txt.setText(sb);

  效果如下图所示:
文本测试


ScrollView嵌套自定义ViewGroup时高度为0的问题

  在使用自定义的ViewGroup时,需要在onMeasure()方法中测量ViewGroup的宽度和高度,之后需要根据测量模式返回不同的结果。通常情况下,只会针对EXACTLY(match_parent,20dp…)和AT_MOST(wrap_content)两种测量模式进行判断。然而,当ViewGroup嵌套在ScrollView中的时候,其高度(假设ScrollView是纵向滚动的)的测量模式将变为UNSPECIFIED。因此在onMeasure()方法的最后,执行setMeasuredDimension()方法时,需要对这种测量模式进行兼容,返回计算好的高度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值