从 CursorAdapter onClick 更新 UI

Update UI from CursorAdapter onClick

我有一个 listView,当用户单击 cardView 时,我从与该职位相关联的 employeeNumber 调用 Web 服务。我从 OkHttp3s enqueue 获取新的 Web 服务调用 onResponse 的数据。如何更新 listView 以从响应中填充新数据?

真的迷路了,因为我知道 listView 正在使用点击时生成的适配器。所以不确定如何调用 listView,以在响应完成后填充适配器。

我的 MainActivity,其中填充了第一个 ListView 并附加了适配器。

public class MainActivity extends AppCompatActivity {

    private ProgressBar mProgressBar;
    EmployeeDBHandler dbHandler;
    private int mStartingEmployeeID = myStartingID;
    private String table = "employees";
    private static final String DATABASE_NAME = "OneTeam";

    @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);
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        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() {
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        Cursor mTopListCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "=" + mStartingEmployeeID, null);
        ListView mTopListView = (ListView) findViewById(R.id.mTopList);
        TopListCursorAdapter topAdapter = new TopListCursorAdapter(this, mTopListCursor);
        mTopListView.setAdapter(topAdapter);
    }

    public void displayBottomList() {
        SQLiteDatabase db = dbHandler.getWritableDatabase();
        Cursor mBottomListCursor = db.rawQuery("SELECT * FROM " + table + " WHERE " + "Employee_number" + "!=" + mStartingEmployeeID, null);

        ListView mBottomListView = (ListView) findViewById(R.id.mDirectReportList);
        BottomListViewAdapter bottomAdapter = new BottomListViewAdapter(this, mBottomListCursor);
        mBottomListView.setAdapter(bottomAdapter);
    }

    @Override
    public void onBackPressed() {
        moveTaskToBack(false);
    }
}

具有按钮 onClick 的 CursorAdapter

public class BottomListViewAdapter extends CursorAdapter {

    private String mEmployeeNumber;
    private EmployeeDBHandler dbHandler;

    public BottomListViewAdapter(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 mTitle = cursor.getString(cursor.getColumnIndexOrThrow("Payroll_title"));
        String mThumbnail = cursor.getString(cursor.getColumnIndexOrThrow("ThumbnailData"));

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

        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 view) {
                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);
                view.getContext().startActivity(mIntent);
            }
        });

        holder.mCardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                cursor.moveToPosition(position);
                mEmployeeNumber = cursor.getString(1);
                Toast.makeText(context, mEmployeeNumber, Toast.LENGTH_SHORT).show();
                dbHandler = new EmployeeDBHandler(context);
                callNewDirectReport();

            }
        });
    }

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

    private void callNewDirectReport() {
        String mDirectReportUrl = "https://b2aproxy.supervalu.com/OneTeam/OneTeamService.asmx/GetDirectReportsWithPicture";

        HttpUrl.Builder urlBuilder = HttpUrl.parse(mDirectReportUrl).newBuilder();
        urlBuilder.addQueryParameter("manager_employee_number", mEmployeeNumber);
        String url = urlBuilder.build().toString();


        OkHttpClient client = getUnsafeOkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, 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);
                    }


            }
        });
    }
}

也许你可以尝试使用Loaders

他们让您将数据源(Content Provider 或其他)与 Activity 或 Fragment 绑定。当加载器处于活动状态时,它们应该监视数据源并在内容更改时提供新结果。

我将向您介绍如何实现它们(尤其是 CursorLoader)的一般方法。我希望清楚:

public class MainActivity extends AppCompatActivity implements
    LoaderManager.LoaderCallbacks<Cursor> {

    private static final int LOADER_INTEGER = 1;

    // ... existing code

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        getLoaderManager().initLoader(LOADER_INTEGER, null, this);
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return new CursorLoader(
            this,
            ContentProvider.CONTENT_URI,
            projection,
            null,
            null,
            sortOrder
        );
    }

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

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

您可以在互联网上阅读很多关于此的内容,例如 here

是一个好的开始

希望对您有所帮助!