0

カスタムの SimpleCursorAdapter とリスト ビューがあります。リストの各行には、名前とボタンがあります。各名前のボタンを押すと、説明付きのダイアログが表示されます。カスタム SimpleCursorAdapter 内で、ボタンの onclick メソッドを設定します。大きなリストがある場合、listView はスクロール バーを取得します。また、下にスクロールすると、リストの最後の行に各行の正しい説明が表示されない理由がわかりません。これは私のコードです:

public class listServicesCursorAdapter extends SimpleCursorAdapter{

private Context context;
private int layout;
private String[] from;
private int[] to;


public listServicesCursorAdapter (Context context, int layout, Cursor c,
        String[] from, int[] to, int flags) {

    super(context, layout, c, from, to, flags);

    this.context = context;
    this.layout = layout;
    this.from = from;
    this.to = to;

}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    final LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(layout, parent, false);

    //Column of BD that we want to recover
    String column = null;

    //Index of the column of  DB
    int nameCol = 0;

    //Result of obtain the index of the column of DB 
    String nombre = null;

    //Name of the textView in the Layout where we want to show the result
    TextView name_text= null;

    String description = null;
    String nameService = null;

    //For each value of DB, we show it in the text view.
    for (int i=0; i<from.length; i++){
        column= from[i];
        nameCol = cursor.getColumnIndex(column);
        name = cursor.getString(nameCol);

        //the values to[i] equals to 0 indicates values that we need but 
                    //that we are not showing in the list directly
        //0 -> description
        if(to[i] == 0){
            description = name;
        }else{
            nameService = name; 
            name_text = (TextView) v.findViewById(to[i]);
            if (name_text != null) {
                name_text.setText(name);
            }
        }
    }


    ImageButton buttonDescription = (ImageButton)  v.findViewById(R.id.imageButtonDescription);

    //we store in a bundle the name and description of the service, so we can use it in
            // the setOnClickListener method.
    final Bundle mArguments = new Bundle();
    mArguments.putString("name", nameService);
    mArguments.putString("description", description);



    buttonDescription .setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v){

            AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());

            builder.setMessage(mArguments.getString("description"))
            .setTitle(mArguments.getString("name"))
            .setCancelable(false)
            .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });

            AlertDialog alert = builder.create();
            alert.show();

        }});

    return v;
}

}

ここでアダプターを呼び出します。

        ServiceSqliteDao serviceDao = new ServiceSqliteDao();
            //get the services for DB
    Cursor mCursorServices = serviceDao.listServices(getActivity());


    if(mCursorServices.getCount()>0){
        //indicate the fields we want to show (from) and where (to)
        String[] from = new String[] { "name", "description"};
        int[] to = new int[] { R.id.checkBoxService,0};
        ListView lvServices = (ListView) v.findViewById (R.id.listViewServices);

        ListServicesCursorAdapter notes = new ListServicesCursorAdapter (getActivity(), R.layout.activity_file_service, mCursorServices, from, to, 0);
        lvServices.setAdapter(notes);

なぜこの動作が発生するのですか?. リスト内のすべての名前を正しく取得しますが、ボタンを水平方向に押して (タブレットを水平に置くことを意味します)、リストにスクロール バーを表示すると、正しい説明が表示されません。一方、タブレットを縦向きに使用すると、リストにスクロール バーが表示されず、各ボタンに適切な説明が表示されます。

これは私のレイアウトです:

<ListView
    android:id="@+id/listViewServices"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1" >
</ListView>

解決策: newView は次のようになります。

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    final LayoutInflater inflater = LayoutInflater.from(context);
    View v = inflater.inflate(layout, parent, false);

    return v;
}

bindView は次のようになります。

@Override
public View bindView(View v, Context context, Cursor cursor) {

    //Column of BD that we want to recover
    String column = null;

    //Index of the column of  DB
    int nameCol = 0;

    //Result of obtain the index of the column of DB 
    String nombre = null;

    //Name of the textView in the Layout where we want to show the result
    TextView name_text= null;

    String description = null;
    String nameService = null;

    //For each value of DB, we show it in the text view.
    for (int i=0; i<from.length; i++){
        column= from[i];
        nameCol = cursor.getColumnIndex(column);
        name = cursor.getString(nameCol);

        //the values to[i] equals to 0 indicates values that we need but 
                    //that we are not showing in the list directly
        //0 -> description
        if(to[i] == 0){
            description = name;
        }else{
            nameService = name; 
            name_text = (TextView) v.findViewById(to[i]);
            if (name_text != null) {
                name_text.setText(name);
            }
        }
    }

/********************************NEW CODE ************************************/

String uniMedition = cursor.getString(cursor.getColumnIndex("unitMedition"));
    if(uniMedition.equals("none")){
        EditText etMedida = (EditText) v.findViewById(R.id.editTextMedida);
        etMedida.setVisibility(View.INVISIBLE);

        TextView tvUniMedition = (TextView) v.findViewById(R.id.textViewUniMedition);
        tvUniMedition .setVisibility(View.INVISIBLE);


    }else{
        EditText etMedida = (EditText) v.findViewById(R.id.editTextMedida);
        etMedida.setVisibility(View.VISIBLE);

        TextView tvUniMedition = (TextView) v.findViewById(R.id.textViewUniMedition);
        tvUniMedition .setVisibility(View.VISIBLE);
        tvUniMedition .setText(uniMedition);

    }

/********************************END NEW CODE ************************************/

    ImageButton buttonDescription = (ImageButton)  v.findViewById(R.id.imageButtonDescription);

    //we store in a bundle the name and description of the service, so we can use it in
            // the setOnClickListener method.
    final Bundle mArguments = new Bundle();
    mArguments.putString("name", nameService);
    mArguments.putString("description", description);



    buttonDescription .setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v){

            AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());

            builder.setMessage(mArguments.getString("description"))
            .setTitle(mArguments.getString("name"))
            .setCancelable(false)
            .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
                }
            });

            AlertDialog alert = builder.create();
            alert.show();

        }});

}

}

今、すべてが正常に動作します!.

4

1 に答える 1

1

なぜこの動作が発生するのですか?. リスト内のすべての名前を正しく取得しますが、ボタンを水平方向に押して (タブレットを水平に置くことを意味します)、リストにスクロール バーを表示すると、正しい説明が表示されません。

ListViewすべての行を表示するスペースがない場合、パフォーマンス上の理由から行ビューがリサイクルされます。問題は、ListView にリサイクルされたビューがない場合にのみ呼び出されるメソッドをSimpleCursorAdapterオーバーライドすること です。そのメソッドが行ごとに呼び出されるときに作業を行うようにオーバーライドします。メソッドでは、行レイアウトを膨張/構築するだけです。newView()bindView()newView()

于 2013-05-24T18:56:48.407 に答える