【问题标题】:Pass onClick from CursorAdapter to another CursorAdapter将 onClick 从 CursorAdapter 传递到另一个 CursorAdapter
【发布时间】:2017-02-15 03:19:13
【问题描述】:

我有 2 个列表视图。一个高于另一个。当用户单击底部列表中的一行时,我正在访问 Web 服务并创建一个新光标并重新填充底部列表。同时,我想把点击的行放到TopListView中。我试图将一个 Intent 从 cursorAdapter 传递给 MainActivity,但这只是用与那里相同的值重新填充了 bottomListView。甚至不调用 Web 服务。 TopListView 没有任何反应。

是否可以将 onClick 的位置从 bottomCursorAdapter 传递到 topCursorAdapter?或者像employee_number这样的变量,我可以在TopAdapter和swapCursor中查询它?如果是这样,则不确定如何交换光标,因为无法判断是否有人单击了 topListView 中的 bottomListView。

我的 TopList 方法

public void displayTopList() {
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        mTopCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
        ListView mTopListView = (ListView) findViewById(R.id.mTopList);
        TopListCursorAdapter topAdapter = new TopListCursorAdapter(this, mTopCursor);
        mTopListView.setAdapter(topAdapter);
    }

我创建的从适配器获取数据以显示 toast 的方法

public void onRowClick(String mEmployeeNumber, String mFirstName) {
        Toast.makeText(getApplicationContext(), "SEND TO TOP LIST " + mEmployeeNumber + " " + mFirstName, Toast.LENGTH_LONG).show();
    }

我正在尝试添加 onRowClick 的 TopAdapter。

public class TopListCursorAdapter extends CursorAdapter {
    public TopListCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.contact_cardview_layout, parent, false);
    }

    @Override
    public void bindView(View view, final Context context, final Cursor cursor) {

        ViewHolder holder;
        holder = new ViewHolder();
        holder.tvFirstName = (TextView) view.findViewById(R.id.personFirstName);
        holder.tvLastName = (TextView) view.findViewById(R.id.personLastName);
        holder.tvTitle = (TextView) view.findViewById(R.id.personTitle);
        holder.mPeepPic = (ImageView) view.findViewById(R.id.person_photo);
        holder.mDetailsButton = (ImageButton) view.findViewById(R.id.fullDetailButton);
        holder.mCardView = (CardView) view.findViewById(R.id.home_screen_cardView);

        String mFirstName = cursor.getString(cursor.getColumnIndexOrThrow("First_name"));
        String mLastName = cursor.getString(cursor.getColumnIndexOrThrow("Last_name"));
        String mPayrollTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
        String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));

        holder.tvFirstName.setText(mFirstName);
        holder.tvLastName.setText(mLastName);
        holder.tvTitle.setText(mPayrollTitle);

        if (mThumbnail != null) {
            byte[] imageAsBytes = Base64.decode(mThumbnail.getBytes(), Base64.DEFAULT);
            Bitmap parsedImage = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
            holder.mPeepPic.setImageBitmap(parsedImage);
        } else {
            holder.mPeepPic.setImageResource(R.drawable.img_place_holder_adapter);
        }


        final int position = cursor.getPosition();
        holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cursor.moveToPosition(position);
                String mEmployeeNumber = cursor.getString(1);
                String mEmail = cursor.getString(8);
                String mFirstName = cursor.getString(2);
                String mLastName = cursor.getString(3);
                String mPhoneMobile = cursor.getString(4);
                String mPhoneOffice = cursor.getString(5);
                String mCostCenter = cursor.getString(10);
                String mHasDirectReports = cursor.getString(7);
                String mTitle = cursor.getString(6);
                String mPic = cursor.getString(9);
                Intent mIntent = new Intent(context, EmployeeFullInfo.class);
                mIntent.putExtra("Employee_number", mEmployeeNumber);
                mIntent.putExtra("Email", mEmail);
                mIntent.putExtra("First_name", mFirstName);
                mIntent.putExtra("Last_name", mLastName);
                mIntent.putExtra("Phone_mobile", mPhoneMobile);
                mIntent.putExtra("Phone_office", mPhoneOffice);
                mIntent.putExtra("Cost_center_id", mCostCenter);
                mIntent.putExtra("Has_direct_reports", mHasDirectReports);
                mIntent.putExtra("Payroll_title", mTitle);
                mIntent.putExtra("ThumbnailData", mPic);
                mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                v.getContext().startActivity(mIntent);
            }
        });
    }

    public static class ViewHolder {
        TextView tvFirstName;
        TextView tvLastName;
        TextView tvTitle;
        ImageView mPeepPic;
        ImageButton mDetailsButton;
        CardView mCardView;
    }
}

【问题讨论】:

  • 你熟悉“回调”这个概念吗?
  • 如果没有,您实际上是在尝试这样做。掌握细节流。 developer.android.com/training/basics/fragments/…
  • 这必须用 Fragments 完成吗?带有我的 onClick 事件的类是 CursorAdapters。我无法覆盖 CursorAdapter 中的 onAttach 方法。
  • 不不,只是“互动”界面。它被称为“回调”。你已经知道 setOnClickListener 了,对吧?同样的想法。在适配器中定义您自己的“setclicked”方法,从您可以访问两个适配器的 Activity 中设置它
  • 我已经更新了我的代码,因为我的回调为空。 stackoverflow.com/q/42218529/4219444 任何帮助将不胜感激。

标签: android listview android-cursoradapter


【解决方案1】:

如果我理解正确,您希望代码知道一个适配器中何时发生单击事件,然后将一些数据发送到另一个适配器。

在这种情况下,您可以简单地定义一个接口,通过包含两者的 Activity 类来桥接适配器之间的“通信”。

例如,这是您定义了接口的适配器。当您单击按钮时,它会被激活。

public class TopListCursorAdapter extends CursorAdapter {

    public interface TopListClickListener {
        void onTopListClick(int position); // Can add more parameters here
    }

    private TopListClickListener callback;

    public TopListCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
        if (!(context instanceof TopListClickListener)) {
            throw new ClassCastException("Context must implement TopListClickListener");
        }
        this.callback = (TopListClickListener) context;
    }

    ...

        holder.mDetailsButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cursor.moveToPosition(position);
                ...
                if (callback != null) {
                    callback.onTopListClick(position); // Can pass more parameters here
                }

在 Activity 中,您可以实现该接口(也就是您的回调)

public class MainActivity extends AppCompatActivity 
    implements TopListCursorAdapter.TopListClickListener // see here

    // private ... topAdapter, bottomAdapter;

    @Override
    public void onTopListClick(int position) {
        // Make sure parameters match the interface ^^^


        // TODO: Get data from topAdapter
        // TODO: database update or arraylist.add to change bottomAdapter
        bottomAdapter.notifyDataSetChanged(); // Update the UI
    }

    // Other code can remain the same

【讨论】:

  • 我是否会像片段一样将数据发送到另一个适配器?在 MainActivity 的方法中只调用 Adapter 而不是 Fragment?尝试传递该点击的所有行信息并将其发送到另一个适配器以将其添加到那里的列表中。
  • 另一个 Fragment 需要附加到 Activity,但我不明白为什么这不起作用。
  • 关于“传递所有行信息”。您可以创建单个 Employee 对象。你也可以implement Parcelable。但是,您不应该通过该方法传递每个单独的字段。
  • 是否有更好的方法来处理在一个适配器中传递单击的行并将其添加到属于不同 CursorAdapter 的另一个列表视图?
  • 我知道该示例适用于 Fragments,但对于您要完成的工作而言,这些并不是真正的“必要”。 Fragment 简单封装了适配器的逻辑,并将其从 Activity 中移走。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-09
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多