简体   繁体   中英

Android custom ListView - Edittext gets cleared when the soft keyboard hides

I have a custom listview which is used to fill up a list, so every item has it's own edittext. When I click in on of them and type in some value, and after that I hide the soft keyboard (little down pointing arrow on the left down corner of the keyboard) the edittext loses the typed in text.

Why and how can I prevent it?

Thanks!

The code of the adapter:

public class CompetitorResultWeightListAdapter extends ArrayAdapter<Competitor> {

    Helper helper = new Helper(getContext());

    private DatabaseReference databaseResult;

    private Activity context;
    private List<Competitor> competitorList;
    private WodResult wodResult;

    public CompetitorResultWeightListAdapter(Activity context, List<Competitor> competitorList) {
        super(context, R.layout.competitor_result_weight_list_layout, competitorList);
        this.context = context;
        this.competitorList = competitorList;
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        helper.logD("in CompetitorResultWeightListAdapter - getView");
        databaseResult = FirebaseDatabase.getInstance().getReference("Competitions").child(helper.getsCompetitionID())
                .child("Wods").child(helper.getsWodID()).child("Results");

        LayoutInflater layoutInflater = context.getLayoutInflater();

        convertView = layoutInflater.inflate(R.layout.competitor_result_weight_list_layout, null, true);

        final ViewHolder viewHolder = new ViewHolder();

        TextView tvCompetitorListName = (TextView) convertView.findViewById(R.id.tvCompetitorListName);
        TextView tvCompetitorListNumber = (TextView) convertView.findViewById(R.id.tvCompetitorListNumber);
        viewHolder.etWeight = (EditText) convertView.findViewById(R.id.etCompetitorResultWeight);
        viewHolder.btnSaveResult = (ImageButton) convertView.findViewById(R.id.btnCompetitorResultRepeat);
        convertView.setTag(viewHolder);

        Competitor competitor = competitorList.get(position);

        tvCompetitorListName.setText(competitor.getCompetitorName());
        tvCompetitorListNumber.setText("Rajtszám: " + competitor.getCompetitorNumber());

        //viewHolder.etWeight.setHint("működik");
        //etCompetitorResultWeight.setInputType(InputType.TYPE_NULL);
        //etCompetitorResultWeight.setTextIsSelectable(true);

        viewHolder.btnSaveResult.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewHolder.etWeight.setHint(viewHolder.etWeight.getText() + " kg");
                helper.logD("Edittext text at position " + position + ": " + viewHolder.etWeight.getText().toString().trim());
                helper.setsCompetitorID(getItem(position).getCompetitorID());
                addWodResult(getItem(position).getCompetitorID(),
                        getItem(position).getCompetitorName(),
                        viewHolder.etWeight.getText().toString().trim());
            }
        });

        return convertView;
    }

    private void addWodResult(String id, String name, String result) {
        helper.logD("in addWodResult");
        helper.logD("id: " + id + ", name: " + name + ", result: " + result);

        wodResult = new WodResult(id, name, result);

        databaseResult.child(helper.getsCompetitorID()).setValue(wodResult).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                if (task.isSuccessful()) {
                    helper.makeToast(getContext().getResources().getString(R.string.wod_result_data_saved), helper.toastShort);
                    //viewHolder.btnRepeatResult.setBackgroundColor(Color.GREEN);
                } else {
                    helper.makeToast(getContext().getResources().getString(R.string.firebase_data_stored_error), helper.toastShort);
                }
            }
        });
    }

    public class ViewHolder {
        EditText etWeight;
        ImageButton btnSaveResult;
    }
}

It sounds like your activity/fragment may be being rebuilt every time the keyboard goes away. Put some log statements in your onStart() to see if this is the case.

At very least you can try adding some configChanges to your Activity in the Manifest:

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

It's also possible that you're completely recreating the ListView/Adapter, which will also reset all the values. Put log statements in where the ListView is populated to see if this is called multiple times. Normally this state should be saved.

You should also consider saving the user's data in a temporary way (preferences, Singleton level object) as soon as they finish typing--you can use this, but there are other ways too: https://developer.android.com/reference/android/text/TextWatcher.html

I also had the same issue... I don't know how efficient it is but what worked for me was:

  1. Create a public static ArrayList variable
  2. Length of this list will be the same as the length of list passed to the adapter
  3. Each Map in the ArrayList will contain all data you are trying to take as input in the ListView
  4. In the adapter, add listeners to the inputs you are taking (Eg. OnTextChangedListener for EditText) and save the inputs into the map of the same position in ArrayList as the input view.
  5. Now, just after the initialization of views in the ListView's Adapter, read values from
    Map of respective position and set the views with the data present in the Map.
  1. Add a onTextChangeListener to your EditText https://stackoverflow.com/questions/12191394/change-edittext-text-from-ontextchangelistener
  2. in afterTextChanged update your input in your local competitorList

What is going on here is that you input data, but the data is going nowhere, when the keyboard hides the list gets redrawn, and the list view will draw the content of your competitorList.

I recommend you to use a RecyclerView instead of the ListView. Take a look at this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM