给子级View和包含的ViewGroup着色之间的区别 [英] Difference between tinting a child View and the containing ViewGroup

查看:76
本文介绍了给子级View和包含的ViewGroup着色之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更好地理解重构选择突出显示"代码(利用着色)时出现的以下情况.

I'm trying to better understand the following situation that arose while refactoring some "selection highlighting" code (to take advantage of tinting).

有一个填充有适配器CodebookAdapter的列表,其中每个项目的定义为:

There's a list that's populated with an adapter, CodebookAdapter, where each item's defined as:

CodebookAdapter列表项布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="#FFFFFFFF">

    <ImageView
      android:id="@+id/item_icon_iv"
      android:layout_width="36dp"
      android:layout_height="36dp"
      android:layout_gravity="center_vertical" />    

    <TextView
      android:id="@+id/item_header_tv"
      android:layout_width="match_parent"
      android:layout_height="20dp"      
      android:textColor="#FF000000"
      android:textSize="14dp"/>
      <!--android:background="#FFFFFFFF"-->
</LinearLayout>

下面的方法HiliteCodeItem()TextViewitem_header_tv设置为 selected .

The method below, HiliteCodeItem(), sets the TextView, item_header_tv, to selected.

我先在list-item本身上设置了background-tint,然后在封闭的TextView上设置了(以避免不必要地突出显示整个布局):

I've set the background-tint first on the list-item itself, and then just on the enclosed TextView (to avoid undesired highlighting of the entire layout):

// option 1 - item_header_tv's background can be omitted/null, highlights ok
/////////////////////////////////////////////////////////////
v.Background.SetTintList(_csl);

// option 2 - item_header_tv's background cannot be omitted/null
/////////////////////////////////////////////////////////////
tv.Background.SetTintList(_csl);

为什么必须在选项2 中明确设置背景(否则tv.Background.SetTintList(_csl);抛出null ex),但是在选项1 item_header_tv中"的背景获取突出显示了?

Why if in option 2 the background must be explicitly set (or else tv.Background.SetTintList(_csl); throws null ex), but in option 1 item_header_tv's background get's highlighted?

封闭列表项目的LinearLayout是否在TextView的背景上进行空检查并实例化一个?

Is the enclosing list item's LinearLayout doing a null check on the background of TextView and instantiating one?

public class Codebook : LinearLayout
{  
     protected virtual void HiliteCodeItem(TextView codeDesc, Code code)        
    {
        _codebookAdapter.SelectedCode = code;

        //codeDesc.SetBackgroundColor(SelectedCodeListItemBgColor);
        codeDesc.Selected = true;       

        _codebookAdapter.NotifyDataSetChanged();
    }

    protected class CodebookAdapter : ArrayAdapter<Code>
    {
        private Codebook _; // explicit outer object ref
        private int _listItemRes;
        private List<Code> _items;    
        private Android.Content.Res.ColorStateList _csl;

        public Code SelectedCode { get; set; }

        public CodebookAdapter(Context context, int listItemRes, List<Code> items, Codebook outer)
            : base(context, listItemRes.Layout, items)
        {
            _ = outer;
            _listItemRes = listItemRes;
            _items = items;

            _csl = _._context.Resources.GetColorStateList(Resource.Color.codebook_code_list_item_color_state_list);
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View v = convertView;
            TextView tv;

            if (v == null)
            {   
                v = _._inflater.Inflate(_listItemRes, parent, false);
                tv = v.FindViewById<TextView>(Resource.Id.item_header_tv);

                // option 1 - item_header_tv's background can be omitted/null, highlights ok
                /////////////////////////////////////////////////////////////
                v.Background.SetTintList(_csl);

                // option 2 - item_header_tv's background cannot be omitted/null
                /////////////////////////////////////////////////////////////
                tv.Background.SetTintList(_csl);
            }
            else
                tv = v.FindViewById<TextView>(Resource.Id.item_header_tv);              

            if (_items == null || _items.Count == 0)
            {
                return v;
            }

            Code code = _items[position];

            if (code != null)
            {   
                if (code == SelectedCode)
                {
                    //tvCodeHeader.SetBackgroundColor(_.SelectedCodeListItemBgColor);
                    tvCodeHeader.Selected = true;
                }
                else
                {
                    //tvCodeHeader.SetBackgroundColor(_.UnselectedCodeListItemBgColor);
                    tvCodeHeader.Selected = false;
                }
            }
        }
    }
}

推荐答案

为什么必须在选项2中显式设置背景(否则tv.Background.SetTintList(_csl);则抛出null),但是在选项1中item_header_tv的背景会突出显示?

Why if in option 2 the background must be explicitly set (or else tv.Background.SetTintList(_csl); throws null ex), but in option 1 item_header_tv's background get's highlighted?

第一个有效是因为您已将android:background="#FFFFFFFF"设置为LinearLayout,代码v = _._inflater.Inflate(_listItemRes, parent, false);指向此LinearLayout.因此它的背景不会被忽略/为空.

The first works because you've set android:background="#FFFFFFFF" to the LinearLayout, the code v = _._inflater.Inflate(_listItemRes, parent, false); points to the this LinearLayout. So it's background is not omitted/null.

如果要SetTintListBackground不能为null,第二行不起作用,因为TextView v中的Background为null.

The Background cannot be null if you want to SetTintList, the second line doesn't work because Background of your TextView v is null.

顺便说一句,像Button这样的控件默认情况下设置了Background,您无需指定Background属性就可以使用SetTintList.

By the way, controls like Button has Background set by default, you don't need to specify the Background property for them to use SetTintList.

这篇关于给子级View和包含的ViewGroup着色之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆