给子级View和包含的ViewGroup着色之间的区别 [英] Difference between tinting a child View and the containing 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()
将TextView
,item_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.
如果要SetTintList
,Background
不能为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屋!