0

I found some similar questions here, but all of their were either really confusing for such a newbie like me or didn't help to solve my problem: I have a TextView tv. By click on it I want to display a custom AlertDialog with EditText + Cancel- and Update-Buttons. By click on Update-Button of my Dialog I want to replace the text of the same TextView (tv) with the value of EditText from Dialog. Here is one of my attepmts:

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

    final TextView tv̶̶C̶̶l̶̶i̶̶c̶̶k̶̶e̶̶d̶ = (TextView) findViewById(R.id.tv_id);
    tv.setText("Initial value");

    tv.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            UpdateDialogFragment updDiag = new UpdateDialogFragment();
            updDiag.show(getFragmentManager(), "dialog");
            tv.setText(updDiag.value); // I try to get the value of EditText like this, but it doesn't work
        }
        });
}

public class UpdateDialogFragment extends DialogFragment {
    String value; // I try to get the value of EditText like this, but it doesn't work
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();

        builder.setView(inflater.inflate(R.layout.edit_tv, null))
                .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        EditText et = (EditText) UpdateDialogFragment.this.getDialog().findViewById(R.id.et_tv);
                        value = et.getText().toString();  // I try to get the value of EditText like this, but it doesn't work
                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        UpdateDialogFragment.this.getDialog().cancel();
                    }
                });
        return builder.create();
    }
}

And my edit_tv.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/et_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:layout_marginTop="40dp"
        android:hint="Enter text ..."
        android:layout_gravity="center_horizontal">

        <requestFocus />
    </EditText>

</LinearLayout>

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yev.tabletasting.MainActivity">

    <TextView
        android:id="@+id/tv_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />    

</RelativeLayout>

In my case the Text of tv will be setted to "" (probably null) after click on "Update". I would be thankful for every advice, thanking you in anticipation!

Yev
  • 321
  • 3
  • 9
  • whats tvclicked and tv? are they two textviews? anyways the textview you want to set text to, declare it globally.. and do `textview.settext(value)` in setPositiveButton onClick after `value = et.getText().toString();` – Dhinakaran Thennarasu Mar 10 '16 at 00:10
  • @Dhina I've edited my code, tvClicked should be just tv (typo). Thank you for your answer, it is correct for my question how I asked it and works, but I'll probably use dynamic textViews in the future like textView tv = new TextView(this); And it will not be possible to declaire it globally – Yev Mar 10 '16 at 19:50

2 Answers2

1

This is what you should have in your TextView onClickListener:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Write new value for TextView");
final EditText editText = new EditText(this);
builder.setView(editText);
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {                 
                    }
                });
AlertDialog dialog = builder.create();
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String newValue = editText.getText().toString();
                        if(newValue.lenght() == 0)
                            Toast.makeText(this, "You need to type something in the editText", Toast.LENGTH_LONG).show();
                        }else{
                            tv.setText(newValue);
                            dialog.dismiss();
                        }
                    });

Maybe some minor changes need to be done because I wrote the code down in here. Hope it helps. Wish you luck :)

LE: you don't need the extra Fragment and xml files for the dialog editText.

victorholo
  • 105
  • 1
  • 11
  • Hi, and thanks for your answer, it was mostly helpful for me. But what if I want to stay by DialogFragment (see why here http://developer.android.com/guide/topics/ui/dialogs.html and here http://stackoverflow.com/a/23946128/1644665) And how can I do it if I want to (or I really need to) assign my editText from a someLayout.xml? – Yev Mar 10 '16 at 20:12
  • By the way, if I do it like you in your answer and I want to allow/tolerate empty Strings "" from editText and the layout_width of tv is setted to wrap_content, my tv is not clicable any more after update to "" (or just gone). Is there also a solution for this problem? – Yev Mar 10 '16 at 20:28
0

Okay, so you haven't really mentioned as to why you prefer to use the DialogFragment rather than just an AlertDialog as what Victor Holotescu answered. But here goes, I tried out your code and managed to receive a NullPointerException when I try to click the Update Button. So I looked at it and modified the code, here it is:

MainActivity

public class MainActivity extends AppCompatActivity {

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

        final TextView tv = (TextView) findViewById(R.id.tv_id);
        tv.setText("Initial value");

        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                UpdateDialogFragment updDiag = new UpdateDialogFragment().newInstance(tv); // Passed the TextView here
                updDiag.show(getFragmentManager(), "dialog");
            }
        });
    }

    public static class UpdateDialogFragment extends DialogFragment {
        String value; // I try to get the value of EditText like this, but it doesn't work
        TextView tvToEdit;

        public UpdateDialogFragment newInstance(TextView tvToEdit){
            UpdateDialogFragment udf = new UpdateDialogFragment();
            udf.tvToEdit = tvToEdit;
            return udf;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            LayoutInflater inflater = getActivity().getLayoutInflater();

            builder.setView(inflater.inflate(R.layout.edit_tv, null))
                    .setPositiveButton("Update", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            EditText et = (EditText) UpdateDialogFragment.this.getDialog().findViewById(R.id.et_tv);
                            value = et.getText().toString();
                            tvToEdit.setText(value);
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            UpdateDialogFragment.this.getDialog().cancel();
                        }
                    });
            return builder.create();
        }
    }
}

I added some TODO comments (labeled with Read comments below. :)) inside the code, check them out. I tested it and it runs properly. Hope this was able to help you in some way. For more information regarding AlertDialogs and DialogFragments, here's a good post -- DialogFragment advantages over AlertDialog.

EDIT

Okay. So I edited it where you just pass a TextView to the UpdateDialogFragment by creating a newInstance method -- referenced it here SetText of TextView in DialogFragment from Calling Activity -- Hope this helps. :)

Community
  • 1
  • 1
AL.
  • 36,815
  • 10
  • 142
  • 281
  • I try to use DialogFragment, because of this guide: http://developer.android.com/guide/topics/ui/dialogs.html and because of this answer: http://stackoverflow.com/a/23946128/1644665 Thanks for your answer, but how I said to @Dhian, you declaire tv globally, what is not suitable for me – Yev Mar 10 '16 at 19:54
  • @Yev I modified the code. Try it out if you still prefer the ***DialogFragment***. – AL. Mar 11 '16 at 00:12
  • Also, just in case, you should add a null checker for the ***TextView*** passed to avoid NPEs. – AL. Mar 11 '16 at 01:09
  • Thank you very very much, you've made my ̶d̶̶a̶̶y̶ week! – Yev Mar 11 '16 at 12:01
  • 1
    And yes, I think using DialogFragment is better, because it manages dialogs lifecycle for example if the user rotates the screen. Without DialogFragment my dialog just disappeared. – Yev Mar 11 '16 at 12:08
  • Hmmm... to the rotation and managing: If I click on tv, my dialog pops up and in this moment I rotate the screen, the tvToEdit becomes null, so I can't handle it in onClick of dialogs Update-Button :( and have the same problem as at the beginning – Yev Mar 11 '16 at 13:30
  • Fragment with rotation is a bit tricky since the activity gets detroyed and then recreated.. I'm unable to try it out right right now, but I've looked around the community and there are posts that are about retaining (or at least, restoring the value of the textviews/edittexts inside dialog fragments after screen rotation. Like this one -- http://stackoverflow.com/a/11942039/4625829 – AL. Mar 12 '16 at 00:43