【问题标题】:Passing object to CursorAdapter getting null将对象传递给 CursorAdapter 得到 null
【发布时间】:2017-02-14 21:37:12
【问题描述】:

我在主要活动中收到一个回调,该回调从 ListView 单击传递一个值对象。如果我举杯吐司,吐司会显示键、值对。我想把它添加到 TopListCursorAdapter 以填充新行。我在 topAdapter.notifyDataSetChanged(); 上得到空值;

不确定如何将mEmployee添加到适配器,我已经尝试过

@Override
public void onBottomListClick(Employee e) {
    mEmployee.add(e);
    dbHandler.addEmployee(e);
    SQLiteDatabase db = dbHandler.getWritableDatabase();
    final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
            "Employee_number" + "=" + e.getEmployee_number(), null);
    // change the adapter's Cursor
    topAdapter.changeCursor(clickedEmployee);
}

但我不想传递一个游标,而 TopListCursorAdapter 想要一个。我只想将 mEmployee 添加到 TopListCursorAdapter 中的现有列表中。

public class MainActivity extends FragmentActivity implements BottomListViewAdapter.BottomListClickListener {
    private ProgressBar mProgressBar;
    EmployeeDBHandler dbHandler;
    private TopListCursorAdapter topAdapter;
    private BottomListViewAdapter bottomAdapter;
    private ArrayList mEmployee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
        dbHandler = new EmployeeDBHandler(getApplicationContext());
        mProgressBar.setVisibility(View.VISIBLE);
        getXMLData();

        //GUI for seeing android SQLite Database in Chrome Dev Tools
        Stetho.InitializerBuilder inBuilder = Stetho.newInitializerBuilder(this);
        inBuilder.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this));
        Stetho.Initializer in = inBuilder.build();
        Stetho.initialize(in);
    }

    public void getXMLData() {
        OkHttpClient client = getUnsafeOkHttpClient();
        Request request = new Request.Builder()
                .url(getString(R.string.API_FULL_URL))
                .build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String responseData = response.body().string();
                final InputStream stream = new ByteArrayInputStream(responseData.getBytes());
                final XMLPullParserHandler parserHandler = new XMLPullParserHandler();
                final ArrayList<Employee> employees = (ArrayList<Employee>) parserHandler.parse(stream);

                for (Employee e : employees) {
                    dbHandler.addEmployee(e);
                }

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mProgressBar.setVisibility(View.GONE);
                        displayTopList();
                        displayBottomList();
                    }
                });
            }
        });
    }

    public void displayTopList() {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.topFragment, new TopFragment());
        fragmentTransaction.commit();
    }

    public void displayBottomList() {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.bottomFragment, new BottomFragment());
        fragmentTransaction.commit();
    }

 @Override
    public void onBottomListClick(Employee e) {
        mEmployee.add(e);
        dbHandler.addEmployee(e);
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        final Cursor clickedEmployee = db.rawQuery("SELECT * FROM " + "employees" + " WHERE " +
                "Employee_number" + "=" + e.getEmployee_number(), null);
        // change the adapter's Cursor
        topAdapter.changeCursor(clickedEmployee);
    }

}

TopListCursorAdapter

public class TopListCursorAdapter extends CursorAdapter {
    private EmployeeDBHandler dbHandler;
    private Activity activityRef;

    public TopListCursorAdapter(Context context, Cursor cursor) {
        super(context, cursor, 0);
        activityRef = (Activity) context;
    }

    @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) {
        dbHandler = new EmployeeDBHandler(context);
        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);
        }

        activityRef.runOnUiThread(new Runnable() {
            @Override
            public void run() {

            }
        });


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

【问题讨论】:

    标签: android android-adapter android-cursoradapter


    【解决方案1】:

    我不想传递一个游标,而 TopListCursorAdapter 想要一个

    当然。你有一个DBHandler,它可以给你一个Cursor

    dbHandler = new EmployeeDBHandler(getApplicationContext());
    

    你有一个addEmployee 方法。

    dbHandler.addEmployee(e);
    

    所以问题是 - 你是如何创建 TopListCursorAdapter 而没有 Cursor 因为它是必需的??


    无论如何,您不应该在适配器中粘贴EmployeeDBHandler
    它只想要一个Cursor。另外,您似乎从未在那里使用过该课程。

    public class TopListCursorAdapter extends CursorAdapter {
        // private EmployeeDBHandler dbHandler; // ** Not needed
        private Context mContext; // Don't need an Activity
    
        public TopListCursorAdapter(Context context, Cursor cursor) {
            super(context, cursor, 0);
            mContext = context; // Just a Context, no Activity
        }
    

    并且您永远不需要在第一次创建 new TopListAdapter 后创建一个,您可以直接在现有适配器上调用 changeCursor

    @Override
    public void onBottomListClick(Employee e) {
        mEmployee.add(e);
        dbHandler.addEmployee(e);
    
        // topAdapter = new TopListCursorAdapter(); // ** Nope
        Cursor newCursor = dbHandler.getEmployees(); // TODO: Implement this
        topAdapter.changeCursor(newCursor); // Updates the UI itself
    
        Intent employeeDetail = new Intent(MainActivity.this, EmployeeFullInfo.class);
        employeeDetail.putExtra("Employee_number", e.getNumber());
        ... 
        startActivity(employeeDetail);
    }
    

    注意:如果您使用use ParcelableEmployee 对象,则不需要Intents 上的一堆putExtragetExtra 方法。


    此外,您可以将 Employee 对象存储为 ViewHolder 的一部分,以简化数据管理。这样,您只需将数据从Cursor 提取到Employee 中,然后ViewHolder 可以保持这一点,因为您在onClick 中重复工作以获取Cursor 数据。

    public static class ViewHolder {
        Employee employee; // See here
        TextView tvFirstName;
        TextView tvLastName;
        TextView tvTitle;
        ImageView mPeepPic;
        ImageButton mDetailsButton;
        CardView mCardView;
    }
    

    【讨论】:

    • 我有一个游标从一个 Fragment 传递给适配器,该 Fragment 有一个 rawQuery 获取一行以添加到 TopListView。这是将员工添加到现有数据库中。该员工已存在于数据库中。
    • 我只是想指出 new TopListCursorAdapter(); 不是你想要的。您应该改为调用changeCursor,但是您发现需要从数据库中查询光标。
    • 试图弄清楚如何获取员工,因为我让 getEmployee 接受一个员工编号,并让 getAllEmployees 接受一个 ArrayList。我可以从 Employee e 传递 getEmployee 的employeeNumber 来将行添加到顶部列表中吗?
    • 然后创建一个新方法和return getReadableDatabase().query(TABLE_NAME, null, null ,null, null, null, null, null)
    • 那不就是把整个表加到TopList吗?我只想将用户在 BottomList 中单击的 1 行添加到 TopList。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 2015-08-26
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多