简体   繁体   English

Android 自定义 ListView - 当软键盘隐藏时 Edittext 被清除

[英]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.当我点击它们并输入一些值,然后我隐藏软键盘(键盘左下角的小向下箭头)时,edittext 会丢失输入的文本。

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.在 onStart() 中放入一些日志语句以查看是否是这种情况。

At very least you can try adding some configChanges to your Activity in the Manifest:至少您可以尝试在 Manifest 中为您的 Activity 添加一些 configChanges:

<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.您也可能完全重新创建 ListView/Adapter,这也将重置所有值。 Put log statements in where the ListView is populated to see if this is called multiple times.将日志语句放在填充 ListView 的位置以查看是否多次调用。 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您还应该考虑在用户完成输入后立即以临时方式(首选项、单例级别对象)保存用户数据——您可以使用它,但还有其他方法: 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创建一个公共静态 ArrayList 变量
  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 ArrayList 中的每个 Map 将包含您尝试作为 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.在适配器中,将侦听器添加到您正在接受的输入(例如,用于 EditText 的 OnTextChangedListener)并将输入保存到与输入视图相同的 ArrayList 位置的地图中。
  5. Now, just after the initialization of views in the ListView's Adapter, read values from现在,在 ListView 的 Adapter 中的视图初始化之后,从
    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-ontextchangelisteneronTextChangeListener添加到您的 EditText https://stackoverflow.com/questions/12191394/change-edittext-text-from-ontextchangelistener
  2. in afterTextChanged update your input in your local competitorListafterTextChanged更新您在本地competitorList afterTextChanged的输入

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.我建议您使用 RecyclerView 而不是 ListView。 Take a look at this看看这个

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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