【问题标题】:Dynamically created views id is always null - findviewbyid not working动态创建的视图 ID 始终为空 - findviewbyid 不起作用
【发布时间】:2019-07-31 19:04:01
【问题描述】:

我正在构建一个应用程序,其中我有一个编辑文本字段并从用户获取数据并将其存储在数据库中它工作正常,现在我使用一个按钮动态创建另一个编辑文本字段(此字段仅创建如果用户希望通过单击按钮),现在动态创建的字段的 id 始终为 null 并显示错误。我将分享我的代码。

对于动态编辑文本:

  //update start
final LinearLayout ll = (LinearLayout) findViewById(R.id.li1);
            mContext = getApplicationContext();

            RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
  //update end


  et1 = new EditText(AddTask.this);
            et1.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT));
            et1.setHint("Enter Item Name");
            et1.setId(View.generateViewId());
    //updates
            layout.addView(et1, params1);
            ll.addView(layout);

访问它:

    EditText item_name = (EditText) findViewById(et1.getId());

运行应用程序时,我在这一行出现错误,像这样。

日志猫:

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: java.lang.NullPointerException:
 Attempt to invoke virtual method 'int android.widget.EditText.getId()' on a null object reference

更新:
这个方法我也试过了,还是没用,

EditText item_name = (EditText) findViewById(getResources().getIdentifier(String.valueOf(et1.getId()), "id", getPackageName()));

(此处数据是使用此代码插入到数据库中的,但在尝试查看数据时,应用程序崩溃了。)

【问题讨论】:

  • 视图中不存在新的et1字段,因为它是动态创建的,所以可以直接使用et1字段而不需要从findViewById获取。
  • 你能推荐一个@SushilMittal 的代码
  • 当两者都是 EditText 那么你为什么要使用这一行进行投射,EditText item_name = (EditText) findViewById(et1.getId());
  • 首先 edittext 用于从用户获取数据并将其存储在 db 中,稍后更新用户打开相同的活动并在 edittext 中进行更改(其中 edittext 视图位于动态创建一个),所以我就是这样投射的。

标签: java android-edittext dynamic-view


【解决方案1】:

首先您需要在创建视图时设置 id。然后你可以尝试获取视图的 id。 How to set id programmatically

你肯定做错了什么。我只是尝试做你正在尝试的事情并且它有效。 这是我的活动

class RootActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_root)

        val layout = findViewById<LinearLayout>(R.id.root)

        val ed = EditText(this).apply {
            hint = "Type here"
            layoutParams = LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
            id = View.generateViewId()
        }
        layout.addView(ed)

        val ed2 = findViewById<EditText>(ed.id)
        Log.e("MEEEEEE", ed2.toString())
    }
}

这里是xml布局

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

【讨论】:

  • 您是否将视图添加到布局层次结构中?当您调用 findViewById(et1.getId()) 时,它会尝试在活动的视图层次结构中查找视图。但是如果你没有添加它,你会得到空指针
  • 我看不懂,你能解释一下或者显示一个示例代码@Yamko
  • 当你创建一个活动时,你调用它的方法setContentView(R.layout.activity_layout)。然后,当您使用findViewById() 搜索视图时,方法会在从 R.layout.activity_layout 膨胀的层次结构中查找视图。在您的情况下,您可以动态创建视图,但不会将其添加到膨胀的层次结构中。因此,当您执行 findViewById(dynamicViewId) 时,它无法在层次结构中找到具有该 ID 的视图。
  • @Yamko 如您所见,我更新了问题,实际上我在线性布局中创建动态视图并使用静态创建的线性布局的参考 ID 显示视图。
  • 更新的答案 -> 添加了适合我的代码。它是 Kotlin,但我认为这已经足够清楚了。如果您需要帮助,请告诉我
【解决方案2】:

首先edittext用于从用户那里获取数据,它将 存储在 db 中,以便以后更新用户打开相同的 活动并在edittext中进行更改(其中edittext 视图是动态创建的),所以我就是这样投射的。

据我了解,EditText (et1) 最初用于从用户那里获取输入以保存数据。稍后查看 EditText (et1) 用于显示数据。

如果您已经拥有 EditText (et1) 的参考,则无需在此处使用 findViewById()

只需在Activity 级别中声明EditText 并使用它来获取输入或在视图上显示数据!

示例代码:

EditText et1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_name);
}

@Override
protected void onResume() {
    super.onResume();
    setView();
    updateView();
}

private void setView() {
    et1 = new EditText(this);
    et1.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
    et1.setHint("Enter Item Name");
}

private void updateView() {
    if (dbHasValues) {
        et1.setText("From DB!!");
    }
}

【讨论】:

  • 这里的用户是创建动态编辑文本视图的人,他们可以根据需要创建任意数量的视图,因此为了确定他们想要更新/修改的编辑文本字段,我需要一个参考ID,(没有任何ID,我怎么能直接从DB中setText)你能理解这里的问题吗!
【解决方案3】:

您可以在布局 xml 页面中定义该 edittext 并为该字段执行可见性消失,当您想要显示该 edittext 时,您可以在单击按钮后使其可见性可见。我猜是一个简单的解决方案。那么元素就在那里它不会抛出空指针异常。

【讨论】:

    【解决方案4】:

    参考:https://developer.android.com/reference/android/view/View.html

    首先你需要使用View.generateViewId()设置id

    public static int generateViewId ()
    

    生成一个适合在setId(int) 中使用的值。此值不会与 aapt 在构建时为 R.id 生成的 ID 值冲突。

    Ex.

    et1.setId(View.generateViewId())
    

    使用前请检查或et1EditText Object is Null or Not.....

    【讨论】:

      猜你喜欢
      • 2016-06-14
      • 1970-01-01
      • 2015-11-20
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多