使用SimpleCursorAdapter在ListView中实现侦听器时发生NULL对象

时间:2016-08-15 15:01:08

标签: android listview simplecursoradapter

我正在创建一个带有列表视图的活动来显示联系人,我正在使用扩展SimpleCursorAdapter的自定义适配器。布局配置如下所示。

活动布局文件: activity_load_contacts.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical">

<android.support.v7.widget.Toolbar
    android:id="@+id/my_toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/contacts_list_view" >
</ListView>
</LinearLayout>

列出项目布局文件: contacts_list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:descendantFocusability="blocksDescendants">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:id="@android:id/text1"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:textAppearance="?android:attr/textAppearanceMedium">
</TextView>
<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false"
    android:id="@+id/load_contact_checkbox"
    android:clickable="false">
</CheckBox>
</LinearLayout>

自定义适配器类:

import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

/**
 * Created by admin on 12/08/2016.
 */
public class LoadContactListAdapter extends SimpleCursorAdapter {

    public LoadContactListAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
        super(context, layout, c, from, to, flags);
    }

    @Override
    public void bindView(View view, Context context, Cursor cur) {
        TextView contactName = (TextView)view.findViewById(android.R.id.text1);
        CheckBox cbx = (CheckBox)view.findViewById(R.id.load_contact_checkbox);

        if(contactName != null) {
            contactName.setText(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
        }
        if(cbx != null) {
            cbx.setId(cur.getInt(cur.getColumnIndex(ContactsContract.Contacts._ID)));
        }
    }
}

客户适配器类工作正常,因为它可以将联系人加载到列表视图。

主要活动类:

import android.annotation.SuppressLint;
import android.app.LoaderManager;
import android.app.SearchManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

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

    /*
     * Defines an array that contains column names to move from
     * the Cursor to the ListView.
     */
    @SuppressLint("InlinedApi")
    private final static String[] FROM_COLUMNS = {
            Build.VERSION.SDK_INT
                    >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
                    ContactsContract.Contacts.DISPLAY_NAME
    };
    /*
     * Defines an array that contains resource ids for the layout views
     * that get the Cursor column contents. The id is pre-defined in
     * the Android framework, so it is prefaced with "android.R.id"
     */
    private final static int[] TO_IDS = {
            android.R.id.text1
    };
    // Define global mutable variables
    // Define a ListView object
    ListView mContactsList;
    // Define variables for the contact the user selects
    // The contact's _ID value
    long mContactId;
    // The contact's LOOKUP_KEY
    String mContactKey;
    // A content URI for the selected contact
    Uri mContactUri;
    // An adapter that binds the result Cursor to the ListView
    private LoadContactListAdapter mCursorAdapter;

    @SuppressLint("InlinedApi")
    private static final String[] PROJECTION =
    {
            ContactsContract.Contacts._ID,
            ContactsContract.Contacts.LOOKUP_KEY,
            Build.VERSION.SDK_INT
                    >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY :
                    ContactsContract.Contacts.DISPLAY_NAME

    };
    // The column index for the _ID column
    private static final int CONTACT_ID_INDEX = 0;
    // The column index for the LOOKUP_KEY column
    private static final int LOOKUP_KEY_INDEX = 1;

    // Defines the text expression
    @SuppressLint("InlinedApi")
    private static final String SELECTION =
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ?
                    ContactsContract.Contacts.DISPLAY_NAME_PRIMARY + " LIKE ?" :
                    ContactsContract.Contacts.DISPLAY_NAME + " LIKE ?";
    // Defines a variable for the search string
    public static String mSearchString;
    // Defines the array to hold values that replace the ?
    private String[] mSelectionArgs = { mSearchString };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_load_contacts);

        // Sets the toolbar as the app bar for the activity
        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);

        // Gets the ListView from the View list of the parent activity
        mContactsList =
                (ListView) findViewById(R.id.contacts_list_view);
        // Gets a CursorAdapter
        mCursorAdapter = new LoadContactListAdapter(
                this,
                R.layout.contacts_list_item,
                null,
                FROM_COLUMNS, TO_IDS,
                SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        // Sets the adapter for the ListView
        mContactsList.setAdapter(mCursorAdapter);

        // Initializes the loader
        getLoaderManager().initLoader(0, null, this);
        // Set the item click listener to be the current fragment.
        mContactsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Log.d("OnContactItemClick: ", "*");
                /*
                 * You can use mContactUri as the content URI for retrieving
                 * the details for a contact.
                 */
                // !!! Here I got a NULL object
                CheckBox cbx = (CheckBox)view.findViewById(R.id.load_contact_checkbox);
                if(cbx != null)
                {
                    boolean isChecked = cbx.isChecked();
                    Log.d("Set checkbox", String.valueOf(isChecked));
                    cbx.setChecked(!isChecked);
                }
                else
                {
                    Log.d("Error: ", view.getClass().toString());
                }
            }
        });
    }
}

在前面的代码中,当我实现setOnItemClickListener()函数时,我尝试获取Checkbox的视图对象。 但是,在这种情况下它将返回一个null对象。我真的不知道为什么导致同样的方法在我的自定义适配器类中正常工作。任何人都可以帮我找到问题所在吗?

我在考虑传递给bindView方法和onItemClick方法的视图对象是否相同? 非常感谢,如果有人能给我一些灵感。

0 个答案:

没有答案