我正试图找出在Kotlin中进行Android View Binding的最佳方法.似乎有一些选择:
findViewById
val button: Button by lazy { findViewById<Button>(R.id.button) }
Run Code Online (Sandbox Code Playgroud)
牛油刀
https://github.com/JakeWharton/butterknife
@BindView(R.id.button) lateinit var button: Button
Run Code Online (Sandbox Code Playgroud)
Kotlin Android扩展程序
https://kotlinlang.org/docs/tutorials/android-plugin.html
import kotlinx.android.synthetic.main.activity_main.*
Run Code Online (Sandbox Code Playgroud)
我对java版本中的findViewById和Butterknife非常熟悉,但Kotlin中每种视图绑定方法的优缺点是什么?
Kotlin Android扩展程序与RecyclerView + ViewHolder模式相匹配吗?
另外,Kotlin Android Extensions如何处理嵌套视图的视图绑定include?
例如:对于使用的活动activity_main.xml,将如何View custom1访问?
activity_main.xml中
<...>
<include layout="@layout/custom" android:id="@+id/custom" />
</>
Run Code Online (Sandbox Code Playgroud)
custom.xml
<...>
<View android:id="@+id/custom1" ... />
<View android:id="@+id/custom2" ... />
</>
Run Code Online (Sandbox Code Playgroud) android findviewbyid kotlin butterknife kotlin-android-extensions
我在Android上遇到了ClassCastException的奇怪问题.一个类不能被转换为同一个类:
java.lang.RuntimeException: Unable to start activity ComponentInfo: java.lang.ClassCastException: com.example.model.BadeWrapper cannot be cast to com.example.model.BadgeWrapper
java.lang.ClassCastException: com.example.events.widgets.TouchyWebView cannot be cast to com.example.events.widgets.TouchyWebView
java.lang.ClassCastException: com.example.friends.widgets.FriendsTabView cannot be cast to com.example.friends.widgets.FriendsTabView
Run Code Online (Sandbox Code Playgroud)
当我找到有错误的行时,它所做的就是通过id查找视图或使用参数创建片段,例如:
FriendsTabView friendsTabView;
friendsTabView = (FriendsTabView) view.findViewById(R.id.friends_bottom_tab_panel);
Run Code Online (Sandbox Code Playgroud)
正如我的BugSense所说,这个问题只发生在带有android 5.0.0(三星SM-G900F)的三星Galaxy S5上.我在其他设备上从未遇到过这个问题:
有没有人遇到过这个问题?有没有办法解决它?
我一直在使用findViewById然后使用ButterKnife 来绑定视图。最近,我看到了这篇文章:https : //proandroiddev.com/new-in-android-viewbindings-the-difference-from-databinding-library-bef5945baf5e,我不太确定如何使用它。
我尝试这样做,但它似乎在 Android Studio 3.4.2 中不起作用
val binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
然后使用这些值,例如:
binding.button....
binding.textView....
我编写了自定义视图,我希望在与自定义视图交互后更新其他一些视图.
主要布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/display_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="text"
android:layout_centerHorizontal="true"
android:tag="name"
android:ems="10" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="@+id/id_number"
android:layout_centerHorizontal="true"
android:layout_below="@id/display_name"/>
<ge.altasoft.custom_views.IdNumber
android:id="@+id/custom_id_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/id_number"
android:paddingLeft="35dip"
custom:firstName="@id/display_name"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
自定义视图布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="@+id/id_number_custom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:paddingRight="35dip" />
<ImageButton
android:id="@+id/load_data_button"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_centerVertical="true"
android:src="@drawable/load_data"
android:layout_toRightOf="@id/id_number_custom" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
自定义视图类,构造函数和侦听器:
private int firstNameViewID;
public IdNumber (Context context, AttributeSet attrs) {
super(context, attrs);
initViews();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IdNumber); …Run Code Online (Sandbox Code Playgroud) 我无法理解为什么findViewById返回错误的元素,这里是类:
public class EventDetailsFragment extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.event_details);
Log.d("First", findViewById(R.id.tuxtView1).getClass().toString());
Log.d("Second", findViewById(R.id.tuxtView2).getClass().toString());
Log.d("Third", findViewById(R.id.imageView1).getClass().toString());
}
}
Run Code Online (Sandbox Code Playgroud)
这是xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/green"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="0dp"
android:layout_height="175dp"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:background="#fff"
android:gravity="right" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="110dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@drawable/ic_event_image" />
<TextView
android:id="@+id/tuxtView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp" />
<TextView
android:id="@+id/tuxtView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tuxtView2"
android:layout_toRightOf="@+id/imageView1"
android:textColor="#555"
android:textSize="20dp" />
</RelativeLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
logcat输出是:
12-26 23:43:20.249: D/First(6789): class android.widget.TextView
12-26 23:43:20.249: D/Second(6789): class android.widget.ImageView
12-26 …Run Code Online (Sandbox Code Playgroud) android textview android-layout android-imageview findviewbyid
可能大多数Android开发者都知道这findViewById不是一个廉价的操作.我们大多数人都知道的另一件事是,您可以通过使用视图层次结构的最小子树来查找其ID的视图,从而提高性能,例如:
<LinearLayout
android:id="@+id/some_id_0">
<LinearLayout
android:id="@+id/some_id_1">
<LinearLayout
android:id="@+id/some_id_2">
<TextView android:id="@+id/textview" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,你可能希望在搜索LinearLayout与id == @id/textview
但是,如果层次结构不是级联,而是在每个级别上进行分支,并且您想要在"叶子"上找到视图,那么会发生什么情况呢?您是findViewById通过寻找父母来执行到达分支的底部,还是findViewById在更大的子集上执行?我认为一个简单的答案是它取决于具体情况,但也许我们可以概括一下它真正依赖的东西?
谢谢
通过更大的子集,我的意思是这样的:
<RelativeLayout android:id="@+id/r0">
<RelativeLayout
android:id="@+id/r1">
<LinearLayout
android:id="@+id/some_id_0">
<LinearLayout
android:id="@+id/some_id_1">
<LinearLayout
android:id="@+id/some_id_2">
<TextView android:id="@+id/textview0" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/some_id_3">
<LinearLayout
android:id="@+id/some_id_4">
<LinearLayout
android:id="@+id/some_id_5">
<TextView android:id="@+id/textview1" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:id="@+id/some_id_6">
<LinearLayout
android:id="@+id/some_id_7">
<LinearLayout
android:id="@+id/some_id_8">
<TextView android:id="@+id/textview2" />
<TextView android:id="@+id/textview3" />
<TextView android:id="@+id/textview4" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
所以现在的问题是,如果我想findViewById在 …
我有一个40个方格的桌子,每个都有一个ID.当我从另一个活动传递Bundle时,我需要从该包中提取Note,Color和ID.然后应用程序将更改/添加文本并更改提取的ID指定的方块的背景.每个方块都有int格式的ID.从其他活动传递的每个ID都是字符串格式.我无法弄清楚如何使它成为findViewById(R.id.passed_id),以及如何让两种不同的格式协同工作.我试图改变每个方格的ID,但是eclipse说ID必须有一个字母和一个数字.我迷路了....这是代码:
package com.tt;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity
{
String gotNotes;
String n;
String gotDOW;
String gotID;
public String Id;
String gotHour;
TextView notes;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
Button settings = (Button)findViewById(R.id.settings);
Bundle gotPackage = getIntent().getExtras();
if (gotPackage != null){
gotNotes = gotPackage.getString("AddedNote");
// if (gotNotes.equals(" ")){n = "Empty";}else n = gotNotes;
//gotDOW …Run Code Online (Sandbox Code Playgroud) 问题是,无论我在何处或如何调用此布局的组件,它们始终返回null.
setView(inflater.inflate(R.layout.search_layout, null))
Run Code Online (Sandbox Code Playgroud)
这很好用.它显示了里面的布局Dialog,但是,子节点总是返回为null findViewById(R.id.some_search_layout_children).
我试图清理我的项目多次,试图实现另一个类我Dialog,叫findViewById()我的主要成员Activity,内部initSearch()方法,以及一个匿名实现内部OnClickListener的Dialog,但都具有相同的结果.我还尝试将孩子们分成独立的Views并以编程方式调用它们:
TextView text = (TextView) findResourceById(R.id.new_independant_textview);
Run Code Online (Sandbox Code Playgroud)
但是,同样的结果.
这是相关代码:
public class Xyz extends Activity {
public void onCreate(...) { // some listener will trigger initSearch() }
private void initSearch() {
AlertDialog.Builder searchDialog = new AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
searchDialog.setTitle("Search Photos");
searchDialog.setMessage("Specify tag and value...");
// R.layout.search_dialog is my custom layour, it displays fine, it works.
searchDialog.setView(inflater.inflate(R.layout.search_dialog, null));
EditText …Run Code Online (Sandbox Code Playgroud) android nullpointerexception android-dialog findviewbyid android-resources
我定义了一个视图,它扩展了RelativeLayout,我想提取其id在layout xml文件中指定的子节点.
在HeaderView.java:
1 package com.example.test;
2
3 public class HeaderView extends RelativeLayout {
4
5 public HeaderView(Context context, AttributeSet attrs) {
6 this(context, attrs, 0);
7
8 TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.HeaderView, 0, 0);
9
10 int headerId = 0;
11 int containerId = 0;
12
13 // find attributes
14 if (arr != null) {
15 if (arr.hasValue(R.styleable.HeaderView_headerview_header)) {
16 headerId = arr.getResourceId(R.styleable.HeaderView_headerview_header, 0);
17 }
18 if (arr.hasValue(R.styleable.HeaderView_headerview_container)) {
19 containerId = arr.getResourceId(R.styleable.HeaderView_headerview_container, …Run Code Online (Sandbox Code Playgroud) 我刚刚从编译器中看到了这个有趣的消息,我不知道它为什么会发生.情况就是这样
例1.
Button test = (Button) findViewById(R.id.someButtonId);
test.setOnClickListener(this);
Run Code Online (Sandbox Code Playgroud)
例2.
findViewById(R.id.someButtonId).setOnClickListener(this);
Run Code Online (Sandbox Code Playgroud)
在第一个例子,我需要通过投返回的对象findViewById来Button.在第二个例子中,我没有必须转换返回的对象,因为我没有使用另一个Button类对象.如果我尝试通过它投射它
((Button)findViewById(R.id.someButtonId)).setOnClickListener(this);
Run Code Online (Sandbox Code Playgroud)
我会收到警告Casting findViewById(R.id.someButtonId) to Button is redundant.
为什么会这样?我不是要删除强制警告.我想知道这背后的逻辑以及如果我不尝试使用返回的对象初始化另一个对象,为什么不需要强制转换findViewById.
android ×10
findviewbyid ×10
butterknife ×1
button ×1
casting ×1
eclipse ×1
kotlin ×1
performance ×1
textview ×1
view ×1