0

I am getting a callback in my main activity that is passing an object of values from a ListView click. If I throw a toast the toast is displaying the key, value pairs. I want to take that and add it to the TopListCursorAdapter to populate a new row. I am getting null on the topAdapter.notifyDataSetChanged();

Not sure how to add mEmployee to the adapter, I have tried to

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

But I do not want to pass a cursor and the TopListCursorAdapter wants one. I just want to add mEmployee to the existing List in 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;
    }
}
Adam Gardner
  • 1,216
  • 1
  • 9
  • 21

1 Answers1

0

I do not want to pass a cursor and the TopListCursorAdapter wants one

Sure. You have a DBHandler which can give you a Cursor.

dbHandler = new EmployeeDBHandler(getApplicationContext());

And you have an addEmployee method.

dbHandler.addEmployee(e);

So the question is - how did you create the TopListCursorAdapter without already having a Cursor since it is required??


Anyways, you should not stick a EmployeeDBHandler in the adapter.
It only wants a Cursor. Plus, you never seem to use that class in there.

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
    }

And you should never need to create a new TopListAdapter after the first creation of one, you can call changeCursor directly on the existing adapter.

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

Note: If you use Parcelable Employee objects, you do not need a bunch putExtra and getExtra methods on the Intents.


Additionally, you can store an Employee object as part of the ViewHolder for simpler data management. That way, you only need to extract data from the Cursor into an Employee, then the ViewHolder can maintain that since you are duplicating the effort within onClick to get the Cursor data.

public static class ViewHolder {
    Employee employee; // See here
    TextView tvFirstName;
    TextView tvLastName;
    TextView tvTitle;
    ImageView mPeepPic;
    ImageButton mDetailsButton;
    CardView mCardView;
}
Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • I have a cursor being passed to the adapter from a Fragment that has a rawQuery getting a row to add to the TopListView. This is adding an employee to the existing database. The employee already exists in the DB. – Adam Gardner Feb 14 '17 at 22:03
  • I was just trying to point out that `new TopListCursorAdapter();` is not what you want. You should instead call `changeCursor`, and however you get that Cursor needs to be queried from the database. – OneCricketeer Feb 14 '17 at 22:06
  • Trying to figure out how to getEmployees as I have getEmployee to accept an employeeNumber and have getAllEmployees that takes an ArrayList. I can just pass the getEmployee the employeeNumber from the Employee e to add just the row to the toplist? – Adam Gardner Feb 14 '17 at 22:11
  • Make a new method then and `return getReadableDatabase().query(TABLE_NAME, null, null ,null, null, null, null, null)` – OneCricketeer Feb 14 '17 at 22:14
  • Wouldn't that just add the entire table to the TopList? I just want the 1 row the user clicked in BottomList to be added to TopList. – Adam Gardner Feb 14 '17 at 22:15
  • I updated my onBottomListClick like you suggested, added a raqQuery and tried to change the Cursor but still get null on topAdapter. – Adam Gardner Feb 14 '17 at 22:41
  • @AdamGardner Did you find your solution? – OneCricketeer Feb 15 '17 at 16:52
  • For the null issue yes, just not for the final solution of adding the click event from bottom list and adding that to the listview in topList. – Adam Gardner Feb 15 '17 at 16:54