1

コメントが関連付けられているアイテムには、次のリスト レイアウトを使用しています。コメントの数は、右側のボックスで示されます。

アイテムリストのレイアウト

現在、onListItemClickハンドラーを使用して別の詳細ビューを起動しています。

public class CustomListFragment extends ListFragment
                                implements LoaderCallbacks<Cursor> {

    private Activity mActivity;
    private CursorAdapter mAdapter;
    private QueryParameters mQueryParameters;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setEmptyText("No data to display");

        mActivity = getActivity();
        if (mActivity == null)  {
            Log.e(getClass().getName(), "Activity is null");
            return;
        }
        // Prepare query.
        mQueryParameters = QueryHelper.getQueryParameters(mActivity);
        if (mQueryParameters == null || !mQueryParameters.isPreparedForLoader()) {
            Log.d(getClass().getName(), "One or more query parameters are null.");
            return;
        }
        mAdapter = new CustomCursorAdapter(mActivity, null, 0);
        setListAdapter(mAdapter);
        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle extras) {
        return new CursorLoader(mActivity,
                mQueryParameters.uri,
                mQueryParameters.fromColumnsLoader,
                mQueryParameters.selection,
                mQueryParameters.selectionArgs,
                mQueryParameters.sortOrder);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        mAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = new Intent(mActivity, ItemDetailsActivity.class);
        intent.putExtra("ITEM_URI", mItemUri);
        mActivity.startActivity(intent);
    }
}

ユーザーが右側のボックス要素をタッチできるように実装したいと思います。このアクションにより、関連する が開始されCommentsActivityます。ただし、ユーザーが左側に触れると、ItemDetailsActivity. どちらの場合も、特定のアイテムの詳細ビューまたはコメントリストをロードできるように、インテントで
を渡す必要があります。 は、を使用してを項目のプロパティにバインドします。itemUri
ListFragmentCursorAdapterTextView

質問:

  • 1 つのリスト項目に 2 回目のタッチ アクションを追加するにはどうすればよいですか?
4

1 に答える 1

4

アダプター自体に関連するコードを投稿していませんでしたが、以前の質問を見つけて、ほとんどそこにいます。

迅速で汚い答え

で、 TextView をbindView()変更して現在の行のインデックスをタグに保存し ( 用)、単純な OnClickListener を追加します。comments_countitemUri

public void bindView(View view, Context context, Cursor cursor) {
    ViewHolder holder = (ViewHolder)view.getTag();
    if (holder == null) {
        ...
        holder.comments_count.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // Get the position from the ViewHolder
                long id = (Long) v.getTag();
                Toast.makeText(v.getContext(), "Comment Click: " + id, Toast.LENGTH_SHORT).show();
            }
        });
    }
    ...
    holder.comments_count.setTag(cursor.getLong(0));
}

ユーザーが行onListItemClick()をクリックすると、コメント ボックスをクリックした場合を除いて、引き続き が呼び出されます。コメント ボックスは、上の OnClickListener を起動し、ユーザーをCommentsActivity. さまざまな値を取得する場所については言及していませんが、それを取得するitemUriには行のIDが必要だと思いました。


優れた回答

前の質問で、繰り返し呼び出しを行っていることに気付きました。Thiago Moreira Rocha のレイアウトは、(ListView の行ごとに) 繰り返し使用するには非常に複雑でした。そのため、別のアプローチを提案します。回答を、アダプター、行レイアウト、および色に関連する部分に分割しましたcomments_count

アダプター
のコードを完全に投稿し、最後に説明します。

public class CustomCursorAdapter extends CursorAdapter {
    private LayoutInflater mInflater;
    private int[] mFrom;

    private OnClickListener commentClick = new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Get the position saved in bindView()
            long id = (Long) v.getTag();
            Toast.makeText(v.getContext(), "Comment Click: " + id, Toast.LENGTH_SHORT).show();
        }
    };

    public CustomCursorAdapter(Context context, Cursor cursor, int flags) {
        super(context, cursor, flags);
        mInflater = LayoutInflater.from(context);
    }

    private void applyColorFilter(Drawable drawable, int count) {
        drawable.clearColorFilter();
        if (count > 0) {
            float saturation = (count * 15) / 100f;
            // The value gets pinned if out of range.
            int color = Color.HSVToColor(new float[] {110f, saturation, 1f});
            drawable.setColorFilter(color, Mode.SRC);
        }
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.title.setText(cursor.getString(mFrom[0]));
        holder.description.setText(cursor.getString(mFrom[1]));

        // Get comments_count and set it as text
        int count = cursor.getInt(mFrom[2]);
        holder.comments_count.setText(count + "");
        holder.comments_count.setTag(cursor.getLong(0));

        // Adjust the color by saturation
        applyColorFilter(holder.comments_color, count);

        // Alternate method, that I explain in the answer
        //   Note: set the solid color in color.xml to #2aff00 
        //holder.comments_color.setAlpha(count * 45);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = mInflater.inflate(R.layout.list_item, parent, false);

        ViewHolder holder = new ViewHolder();
        holder.title = (TextView)view.findViewById(R.id.title);
        holder.description = (TextView)view.findViewById(R.id.description);
        holder.comments_count = (TextView)view.findViewById(R.id.comments_count);
        holder.comments_count.setOnClickListener(commentClick);
        holder.comments_color = ((LayerDrawable) holder.comments_count.getBackground()).findDrawableByLayerId(R.id.color);

        view.setTag(holder);

        return view;
    }

    @Override
    public Cursor swapCursor(Cursor newCursor) {
        if(mFrom == null && newCursor != null) {
            mFrom = new int[] {newCursor.getColumnIndex(TITLE), newCursor.getColumnIndex(DESCRIPTION), newCursor.getColumnIndex(COMMENTS_COUNT)};
        }
        return super.swapCursor(newCursor);
    }

    private class ViewHolder {
        TextView title;
        TextView description;
        TextView comments_count;
        Drawable comments_color;
    }
}

私はいくつかの変更を加えました:

  • mFrom使用している列のインデックスを保持します。列インデックスを取得する必要があるのは1 回だけです。カーソルを変更しない限り変更されません。
  • commentsClickは、すべての行に使用する汎用の OnClickListenerの 1 つであり、ViewHolder
  • HSVの色を変更する方法をアダプタに持ち込み、それを呼び出しましたapplyColorFilter()
  • の1 つをチェックするのではなく、の作成に移動しましViewHoldernewView()nullbindView()

行のレイアウト
コメントの色を少し変えていることに気付いたでしょう。これは、単純な行のレイアウトを使用しているためです。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp" >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/comments_count"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/title"
        android:layout_toLeftOf="@+id/comments_count"
        android:textAppearance="?android:attr/textAppearanceSmall" />

    <TextView
        android:id="@+id/comments_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="15dp"
        android:background="@drawable/comments_layers"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

( Thiago Moreira Rocha のレイアウトは機能しますが、ネストされた ViewGroup はやり過ぎのように見えます。子が 1 つしかない ViewGroup がある場合は、通常、それらが代わりになります。)

LayerDrawable を使用して、2 つの LinearLayouts を置き換えます。これについては、手順で説明します。 まず、境界線 ( border.xml) は、前のものと非常によく似ています。

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="10dp" />
    <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
    <solid android:color="#ffffff" />
    <stroke android:width="2dp"
        android:color="#000000" />
</shape>

(パディングはストロークの幅であることに注意してください。)

次に、調整可能な背景色 ( color.xml):

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="10dp" />
    <padding android:bottom="10dp" android:left="10dp" android:right="10dp" android:top="10dp" />
    <solid android:color="#ffffff" />
</shape>

最後に、LayerDrawable を作成して 2 つの画像を結合します ( comments_layers.xml)。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item 
        android:id="@+id/border"
        android:drawable="@drawable/border" />
    <item 
        android:id="@+id/color"
        android:drawable="@drawable/color" />
</layer-list>

(オプション)
で HSV 値の彩度を調整しますapplyColorFilter()が、これは緑の背景のアルファを調整するのと同じようです。これが当てはまる場合、アルファ値の変更ははるかに簡単な作業です。で私のコメントを見つけてbindView()ください:

  1. コメントアウトapplyColorFilter(holder.comments_color, count);
  2. コメント解除holder.comments_color.setAlpha(count * 45);
  3. color.xmlファイルを開き、要素のcolor属性をからに変更しますsolid#ffffff#2aff00

実のところ、私は以前にこのような LayerDrawables を使用したことがありませんでした。より速い方法があるかもしれませんが、これはかなり巧妙だと思います。

于 2012-09-14T21:04:01.083 に答える