如何将多个触摸操作附加到单个列表项? [英] How to attach multiple touch actions to a single list item?

查看:30
本文介绍了如何将多个触摸操作附加到单个列表项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对具有关联评论项目使用以下列表布局.评论的数量由右侧的框指示.

I am using the following list layout for items that have associated comments. The number of comments are indicated by the box on the right side.

目前,我正在使用 onListItemClick 处理程序来启动另一个 details 视图.

Currently, I am using the onListItemClick handler to launch another details view.

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,以便特定 details 视图或 comments 列表项目可以加载.
ListFragment 使用 CursorAdapterTextView 绑定到 item 的属性.

I would like to implement that the user can touch the box element on the right. This action should then start the associated CommentsActivity. When the user touches the left side, however, it should still launch the ItemDetailsActivity.
In both cases, I need to pass the itemUri with the intent so that either the details view or the comments list for the particular item can be loaded.
The ListFragment uses a CursorAdapter to bind the TextViews to the properties of an item.

问题:

  • 如何将第二个触摸操作附加到单个列表项?

推荐答案

您没有发布任何与适配器本身相关的代码,但我找到了您的 上一个问题 并且您已经完成了大部分工作.

You hadn't posted any code relating to the adapter itself, but I found your previous question and you are most of the way there.

bindView()中,让我们修改你的comments_count TextView以保存标签中当前行的索引(对于你的itemUri)并添加一个简单的 OnClickListener:

In bindView(), let's modify your comments_count TextView to save the index of the current row in the tag (for your itemUri) and add a simple OnClickListener:

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 才能获取它.

When the user clicks on the row it will still call onListItemClick(), except if they click on the comments box. The comments box fires the OnClickListener above where you can direct the user to your CommentsActivity. You didn't mention where you fetch the different values for itemUri but I assumed you need the row's id to get it.

在您之前的问题中,我注意到您进行了一些重复调用,并且 Thiago Moreira Rocha 的布局非常复杂,需要重复使用(对于每个 ListView 行).所以我提出了一种不同的方法.我已将我的答案分为与 comments_count 的适配器、行布局和颜色相关的部分:

In your previous question, I noticed that you are making some repetitive calls and that Thiago Moreira Rocha's layout was extremely complex to be used repeatedly (for every ListView row.) So I propose a different approach. I've divided my answer into parts relating to the adapter, row layout, and colors for comments_count:

适配器
我将完整发布代码,然后在底部解释:

The Adapter
I'll post the code in full and then explain at the bottom:

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 保存您正在使用的列的索引.您只需要获取列索引一次,除非您更改 Cursor
  • ,否则它不会更改
  • commentsClick一个通用的 OnClickListener,我用于每一行,我在创建 ViewHolder 时设置它
  • 我将您更改 HSV 颜色的方法引入了适配器,并将其称为 applyColorFilter()
  • 我将创建 ViewHolder 移动到 newView() 而不是检查 bindView() 中的 null>
  • mFrom holds the indices of the columns that you are using. You only need to get the column index once, it won't change unless you change the Cursor
  • commentsClick is one generic OnClickListener that I use for every row and I set it while creating a ViewHolder
  • I brought your method for changing the HSV color into the adapter and called it applyColorFilter()
  • I moved creating the ViewHolder into newView() rather than checking for a null one in bindView()

行布局
你可能注意到我改变了评论的颜色有点不同,那是因为我使用了更简单的行布局:

The Row Layout
You probably noticed that I change the comments' color a little differently, that is because I use a simpler row layout:

<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 的布局 有效,但嵌套的 ViewGroups 似乎有点矫枉过正.任何时候您只有一个 ViewGroup孩子,他们通常是另一种选择.)

(While Thiago Moreira Rocha's layout works, the nested ViewGroups seem like overkill. Anytime you have a ViewGroup with only one child, their is usually an alternative.)

我使用一个 LayerDrawable 来替换两个 LinearLayouts,我将分步解释.一、边框(border.xml),和上一个很像:

I use a LayerDrawable to replace the two LinearLayouts, that I will explain in in steps. First, the border (border.xml), very similar to the previous one:

<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>

(注意填充是笔划的宽度.)

(Notice the padding is the width of the stroke.)

二、可调背景色(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 来组合两个图像(comments_layers.xml):

Last, I created a LayerDrawable to combine the two images (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>

<小时>

(可选)
您可以在 applyColorFilter() 中调整 HSV 值的饱和度,但这似乎相当于调整绿色背景的 alpha.如果这是真的,更改 alpha 值是一项简单得多的任务.在 bindView() 中查找我的评论:


(Optional)
You adjust the saturation of your HSV value in applyColorFilter(), but it seems that this is the equivalent to adjusting the alpha of a green background. If this is true, the changing the alpha value is a much simpler task. Find my comments in bindView():

  1. 注释掉applyColorFilter(holder.comments_color, count);
  2. 取消注释holder.comments_color.setAlpha(count * 45);
  3. 打开我的 color.xml 文件并将 solid 元素的 color 属性从 #ffffff 更改为#2aff00
  1. Comment out applyColorFilter(holder.comments_color, count);
  2. Uncomment holder.comments_color.setAlpha(count * 45);
  3. Open my color.xml file and change the color attribute of the solid element from #ffffff to #2aff00

<小时>

说实话,我以前从未使用过这样的 LayerDrawables,可能有更快的方法,但我认为这很巧妙.


In all truth I had never used LayerDrawables like this before, there may be a faster way, but I think this is pretty slick.

这篇关于如何将多个触摸操作附加到单个列表项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆