1

私はCursorAdapter自分のを処理するためにを使用していListActivityます:

public class Mclass extends ListActivity{
...
TheAdapter mAdapter;
public static HashMap<Long, Boolean> shown = new HashMap<Long, Boolean>();
...

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
         Boolean tmp = shown.get(id); 
        if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
            shown.put(id, true);
        } else {
            shown.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
        }
    mAdapter.notifyDataSetChanged();
         }

}

CursorAdapterそして、拡張してオーバーライドする私のアダプタークラスbindView

@Override
public void bindView(View view, Context context, Cursor cursor) {
    String listText= cursor
            .getString(cursor
                    .getColumnIndexOrThrow(DataHandler.MY_TEXT));

long id = cursor.getLong(cursor.getColumnIndexOrThrow(DataHandler.ROW_ID)); 
    if (Mclass.shown.get(id) != null) {
        TextView m_text = (TextView) view
                .findViewById(R.id.my_text);
        if (m_text != null) {
            m_text.setVisibility(Mclass.shown.get(id)? View.VISIBLE:
                     View.GONE);

            if (m_text.isShown())
                m_text.setText("STRING");
   }
}

私のリストアイテムのレイアウトはxmlファイルで定義されていますlist_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#DDDDDD"
android:orientation="horizontal" >

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/my_image"
        android:layout_width="wrap_content"
        android:layout_height="0dip"
        android:layout_weight="1"
        android:paddingRight="1dip"
        android:paddingTop="1dip"
</LinearLayout>

/*
 *I want to toggle this text view's visibility
 */
<TextView
    android:id="@+id/my_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"//VISIBILITY defined here
    android:paddingBottom="2dip"
    android:paddingLeft="4dip"
    android:paddingRight="4dip"
    android:paddingTop="5dip" />
 </LinearLayout>

TextView内のレイアウトでの表示を切り替えるにはどうすればよいonListItemClickですか?私はもう試した:

TextView mTextView = (TextView) v.findViewById(R.id.my_text);
mTextView.setVisibility(mTextView.isShown()? View.GONE: View.VISIBLE);
mAdapter.notifyDataSetChanged();

しかし、クリックしたものに関係なく、ランダムに切り替えるリスト項目を選択しているようです。

4

3 に答える 3

3

非表示にする行のIDを保存する必要があります。これらのIDを保存するために、アクティビティにフィールドを作成できます。

HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();

ここで、キーは行の長いIDであり、ブールオブジェクトはステータスを表しますTextView(false-消え、trueは表示されます)。onListItemClick()クリックした行のIDをそのフィールドに追加します。

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
         Boolean tmp = positionHide.get(id); 
        if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
            status.put(id, true);
        } else {
            status.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
        }
        mAdapter.notifyDataSetChanged();
    }

bindView()メソッドも変更します。

@Override
public void bindView(View view, Context context, Cursor cursor) {
    String listText = cursor.getString(cursor
            .getColumnIndexOrThrow(DataHandler.MY_TEXT));
    long pos = cursor.getLong(cursor.getColumnIndex(DataHandler.ID)); // DataHandler.ID will point to the column _id
TextView m_text = (TextView) view.findViewById(R.id.my_text);

    if(status.get(pos) == null) {
//id is not yet in the hashmap so the value is 
//by default false, the TextView is invisible
    m_text.setVisibility(View.GONE);

    } else {
        // we have the value in the
        // Hashmap so see what it is and set the
    // textview visibility from this value

        if (tmp.booleanValue()) {
          m_text.setVisibility(View.VISIBLE);
             } else {
                 m_text.setVisibility(View.GONE);
                   }
          }
    if (m_text != null)
     m_text.setText(listText);  

}

これを機能させるには、データベースに列を含める必要があります_id INTEGER PRIMARY KEY AUTOINCREMENT(また、クエリに追加する必要があります)。

于 2012-03-03T13:35:56.933 に答える
1

問題は、ビューがリストビューで再利用されることです。これは、100個のアイテムで構成されるリストがある場合でも、ビューインスタンスは10個程度しかないことを意味します(画面に収めることができる量によって異なります)。あなたが見ることができるならば、メソッドbindViewはパラメータとして再利用するためにビューを取ります。

これまでに行ったことは、たとえばリストの23番目の項目を表示し、テキストボックスを非表示にするビューです。23番目のアイテムを画面からスクロールアウトすると、そのビューは再利用されますが、値のみが33番目のアイテムのデータに置き換えられ、再利用しているビューに設定した可視性とその他のパラメーターは同じままです。

すべてのリストアイテムにステータスブール値を追加し、アダプタのbindViewで、アイテムの現在必要な状態に応じてテキストボックスの表示を切り替えます。

確認すべきもう1つの重要な点は、アイテムをクリックしても、bindViewメソッドが呼び出されないことです。したがって、変更を即座に行うには、onClickメソッドの表示も切り替える必要があります。これを見逃した場合、ビューの外観は、アイテムがスクロールアウトされて再びスクロールインされた後にのみ変更されます。これは、bindViewが可視性ブール値をチェックするときです。

「データ」の変更をDataSetObserversに通知し、ListViewがすべての表示アイテムに対してbindViewを呼び出せるようにする方がより効率的ですが、リソースをより多く消費します。

HashMap<Long, Boolean> positionHide = new HashMap<Long, Boolean>();
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
         Boolean tmp = positionHide.get(id); 
        if (tmp == null) { // if null we don't have this key in the hashmap so we added with the value true
            positionHide.put(id, true);
            tmp = true;
        } else {
                        tmp = !tmp.booleanValue();
            positionHide.put(id, !tmp.booleanValue()); // if the value exists in the map then inverse it's value
        }
        // You should also hide the text view, because bindView will not be called until the list item is scrolled out and in again
                TextView m_text = (TextView) view.findViewById(R.id.my_text);
        if (m_text != null) {
              if(tmp) {
                            // We should hide the text view
                            m_text.setVisibility(View.GONE);
                  } else {
                        // We should display the text view
                            m_text.setVisibility(View.VISIBLE);
                  }
        } 
    }


@Override
public void bindView(View view, Context context, Cursor cursor) {
    String listText = cursor.getString(cursor
            .getColumnIndexOrThrow(DataHandler.MY_TEXT));
            TextView m_text = (TextView) view.findViewById(R.id.my_text);
    if (m_text != null) {
          m_text.setText(listText);
          long pos = cursor.getLong(cursor.getColumnIndex(DataHandler.ID)); // DataHandler.ID will point to the column _id
          if((positionHide.get(pos) != null)&&(positionHide.get(pos))) {
                        // We should hide the text view
                        m_text.setVisibility(View.GONE);
              } else {
                    // We should display the text view
                        m_text.setVisibility(View.VISIBLE);
              }
            }
}

これを機能させるには、データベースに列を含める必要があります_id INTEGER PRIMARY KEY AUTOINCREMENT(また、クエリに追加する必要があります)。

于 2012-03-03T13:38:04.190 に答える
1

アクティブなビューには使用ListViewしないでください。代わりにTableLayoutまたはLinearLayoutを使用してみてください。詳細については、このブログ投稿を参照してください。ただし、チェックボックス用ですが、アクティブなビューすべてに当てはまります。

于 2012-03-03T14:06:35.943 に答える