Dynamically created views id is always null - findviewbyid not working

1.1k views Asked by At

I am building an app, in which I have a edit text field and getting data from user and storing it in database it is working fine , now I used a button to dynamically create another edit text field (this field is created only if the users want by using button click) , now the id of the dynamically created field is always null and shows error. I will share my code.

for dynamic edit text:

  //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);

for accessing it:

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

when running the app , im getting error in this line , like this.

logcat:

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

updates :
i also tried this way , still no use guys ,

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

(here the data was inserting into the database using this code , but when trying to view the data , the app crashes.)

4

There are 4 answers

7
Yamko On

Firstly you need to set id, when you create view. Then you can try to get view's id. How to set id programmatically

It's for sure that you doing something wrong. I just tried to do what you are trying and it works. Here is my activity

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())
    }
}

Here is xml layout

 <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"/>
1
Gokul Nath KP On

first the edittext is used for getting the data from user and it will be stored in db , and for later updation the user opening the same activity and doing the changes in the edittext (where the edittext view is dynamically created one) , so i'm casting like that.

As per my understanding the EditText (et1) is being used to get input from user initially for saving the data. Later for viewing the EditText (et1) is used to display the data.

Here you don't need to findViewById() when you already have reference for EditText (et1).

Just declare the EditText in Activity level and use the same for getting input or displaying data on the view!

Sample Code:

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!!");
    }
}
0
sonu kumar prashant On

You can define that edittext in layout xml page and do visiblity gone for that field and when you want to show that edittext then you can make it visiblity visible after button click. A simple solution i guess. Then the element will be there it will not throw null pointer exception.

0
Ashvin solanki On

Ref : https://developer.android.com/reference/android/view/View.html

first you need to set id with the use of View.generateViewId()

public static int generateViewId ()

Generate a value suitable for use in setId(int). This value will not collide with ID values generated at build time by aapt for R.id.

Ex.

et1.setId(View.generateViewId())

please check before use or et1 EditText Object is Null or Not.....