0

カスタム ビューの listView があります。各ビューには editText が含まれています。getView() で作成した editText 変数にリスナーを追加しようとしています。問題は、リスナーを作成するときに、最終的にしない限り editText 変数を使用できないことですが、最終的にすると、行が再利用されるときに問題が発生すると思います。これは私の問題の簡単な例です:

private class MyAdapter extends ArrayAdapter<Date>{

    public MyAdapter(Context context, int resource, int textViewResourceId,
            List<Date> objects) {

        super(context, resource, textViewResourceId, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        if(convertView==null){
            LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            row = inflater.inflate(R.layout.listview_cell_single, parent, false);
        }else{
            row = convertView;
        }

        EditText et = (EditText) row.findViewById(R.id.editText_single);
        et.setText("" + position);

        et.setOnFocusChangeListener(new OnFocusChangeListener() {
            public void onFocusChange(View v, boolean hasFocus) {
                if(!hasFocus){
                    et.setText("You edited row: " + position);
                    //Error: et must be final, position must be final
                }
            }
        });
4

2 に答える 2

0

これはスコープ間の契約、つまりスタック対ヒープです。スタック上に作成された参照は、参照が基本的にそれを使用する匿名クラス (OnFocusChangeListener) によってバインドされるため、参照が変更されない (変更できない) ことを宣言するために最終的なものである必要があります。

各スタックは EditText オブジェクトへの参照の独自のコピーを取得するため、参照は再利用されません。

于 2013-08-19T12:00:36.810 に答える
0

EditText etでこれをクラス変数として宣言する必要がありますMyAdapter。として

private class MyAdapter extends ArrayAdapter<Date>{
 EditText et;

}

そして、メソッドでそれを開始しgetView();ます。

 @Override
    public View getView(int position, View convertView, ViewGroup parent) {

   //do your stuff
   ........
    et=(EditText) row.findViewById(R.id.editText_single);

}
于 2013-08-19T11:51:31.800 に答える