为什么我们需要在安卓中进行视图转换?

huangapple go评论129阅读模式
英文:

why we need to casting views in android?

问题

我只是在想为什么我们在使用findViewById()方法初始化视图时实际上要进行视图转换,我的意思是findViewById()方法会返回什么,以及为什么我们需要对结果进行转换。

TextView txtview;

txtview = (TextView) findViewById(R.id.textViewID);
英文:

I'm just was wondering why we are actually casting views when we initialize it by using findViewById() method, I mean what does findViewById() method return back, and why we need to cast the result.

TextView txtview;

txtview = (TextView) findViewById(R.id.textViewID);

答案1

得分: 2

注意:您不是在初始化,而是从一个已经创建的带有子视图的视图对象中进行赋值。

在过去,该方法的签名为:

public View findViewById(@ResId int id)

从View向任何子类型(TextView、EditText、ImageView等)的向下转换是必要的,旧文章仍在使用这种方法。

现在,该方法的签名是通用的:

public <T extends View> T findViewById(@ResId int id)

意味着它返回被转换为T的值,T在赋值声明的左侧解析(在等号之前),因此我们可以简单地执行以下操作:

TextView t = view.findViewById(R.id.tv_x);

T的值是赋值语句左侧的TextView。

还请考虑以下方法签名:

void x(TextView t, ImageView i)

在调用此方法时,您可以推断出T,从而导致使用Textview和ImageView调用该方法,而不是超类View:

x(view.findViewById(R.id.tv_x), view.findViewById(R.id.iv_x))

而这种赋值将需要向下转型:

View v = view.findViewById(R.id.tv_x);
//v.text = "x" 在这里,我们不知道类型未被推断为TextView
((TextView) v).text = "x"; //需要不安全的向下转型

附:下面View的T的推断类型是不安全的。

英文:

Note: You are not initializing, you are assigning there from a already created view object with childs

In the past the signature of the method was

public View findViewById(@ResId int id)

The downcast from View to any subtype (TextView, EditText, ImageView, etc) was necessary and old articles still uses this method.

Now days the signature is generic as:

public &lt;T extends View&gt; T findViewById(@ResId int id)

Meaning it returns it value cast to T, T is resolved with the left side of the assignment declaration (before the equals) so we can simply do:

TextView t = view.findViewById(R.id.tv_x);

The value of T is TextView from the left side of the assignment.

Also consider the following method signature:

void x(TextView t, ImageView i)

You can infer T while calling this resulting the method being called with a Textview and a ImageView instead of the super class View:

x(view.findViewById(R.id.tv_x), view.findViewById(R.id.iv_x))

While this assignment would need downcasting:

View v = view.findViewById(R.id.tv_x);
//v.text = &quot;x&quot; HERE we don&#39;t know the type was not infered to TextView
((TextView) v).text = &quot;x&quot;; //unsafe downcasting necessary

Ps: the inferred type of T is unsafe below View

答案2

得分: 0

这种转换实际上是可选的。请在这里检查,该调用返回视图,否则返回null。

另外,如果您使用视图绑定(view binding),甚至不需要使用findViewById

英文:

This casting is actually optional. Please check here that this call returns the view or null otherwise

Alternatively if you use view binding you don't even need to use findViewById

huangapple
  • 本文由 发表于 2020年10月21日 05:34:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/64453656.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定