欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android使用之CursorAdapter

程序员文章站 2024-02-09 17:03:04
...

CursorAdapter使用说明

运用场景

主要用于在ListView或者GridView等中动态显示数据库中创建的数据,功能与AdapterView相似。

CursorAdapter具体实现步骤

实现步骤

  1. 创建XML文件用于将来Item显示样式
  2. 新建Class创建其相应的构造函数
  3. 继承CursorAdapter并重写相应的子方法
  4. 创建对应Activity的XML文件实现相应的显示控件
  5. 在Activity中实现LoaderManager.LoaderCallbacks获得该Content中的Cursor,用于将来Adapter的数据读取
  6. 在Activity中的相应控件中载入Adapter

1.1 Item显示样式

在Layout文件夹下创建一个XML文件用于实现将来在ListView中的Item需要显示的样式。这些并定义将来需要更改数据的id。

代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="10"
        android:orientation="vertical">
        <!--显示第一行-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/the_first_line">
            <!--用于显示编号-->
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:id="@+id/display_number"
                android:layout_weight="1">
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="编号:" />
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:id="@+id/number_text_view"
                    android:text="223" />
            </LinearLayout>
            <!--显示体重-->
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:id="@+id/display_weight"
                android:layout_toRightOf="@+id/display_number"
                android:layout_weight="1">
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="体重:"
                    />
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="20"
                    android:id="@+id/weight_text_view"/>
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="Kg" />
            </LinearLayout>
        </LinearLayout>
        <!--显示第二行-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:id="@+id/the_second_line">
            <!--用于显示品种-->
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:id="@+id/display_breed"
                android:layout_weight="1">
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="品种:" />
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:id="@+id/breed_text_view"
                    android:text="家猪" />
            </LinearLayout>
            <!--显示吃食次数-->
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:id="@+id/display_eat_times"
                android:layout_weight="1">
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="吃食次数:" />
                <TextView
                    style="@style/DisplayItemBriefText"
                    android:text="2"
                    android:id="@+id/eat_times_text_view"/>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <ImageView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:src="@drawable/ic_keyboard_arrow_right_black_48dp"
        android:layout_gravity="center"/>
</LinearLayout>
XML结果

Android使用之CursorAdapter

1.2 创建Class

构造方法

public BriefInformationAdapter(Context context, Cursor cursor)

创建该构造方法是为了将来在Activity中实现的时候能够将curosr中的数据传输进该Adapter,即其中的cursor就包含了需要的所有数据

代码
public class BriefInformationAdapter extends CursorAdapter {

    /**
     * 构造函数{@link BriefInformationAdapter}
     * @param context   显示的环境
     * @param cursor    显示的数据
     */
    public BriefInformationAdapter(Context context, Cursor cursor){
        super(context,cursor,0/*flag*/);
    }
  }

1.3 在Class中继承CurosrAdapter

重写子方法

继承CurosrAdapter后需要重写两个方法,分别是:
- public View newView(Context context, Cursor cursor, ViewGroup parent)
- public void bindView(View view, Context context, Cursor cursor)

newView方法用于实现创建新的View,将前文创建的Item样式在这里扩展显示。

bindView方法用于实现在新创建的View中将数据库中对应的数据显示到对应的id控件上。

代码
/**
 *用于适配显示在{@link EditPetInformationActivity}中的宠物的简略信息
 */
public class BriefInformationAdapter extends CursorAdapter {

    /**
     * 构造函数{@link BriefInformationAdapter}
     * @param context   显示的环境
     * @param cursor    显示的数据
     */
    public BriefInformationAdapter(Context context, Cursor cursor){
        super(context,cursor,0/*flag*/);
    }

    /**
     * 创建一个新的View用于显示
     * @param context   显示环境
     * @param cursor    从中获取显示的数据
     * @param parent    新的View是依附在那个环境中
     * @return 返回新的listView
     */
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        /**膨胀显示的item的样式display_item**/
        return LayoutInflater.from(context).inflate(R.layout.display_item,parent,false);
    }

    /**
     * 用于将cursor中的数据匹配到相对应的标签中
     * @param view      newView方法中创建的view
     * @param context   显示环境
     * @param cursor    从该cursor中提取数据
     */
    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        /**
         * 确定需要显示的TextView
         */
        TextView numberTextView=(TextView) view.findViewById(R.id.number_text_view);
        TextView breedTextView=(TextView) view.findViewById(R.id.breed_text_view);
        TextView weightTextView=(TextView) view.findViewById(R.id.weight_text_view);
        TextView eatTimesTextView=(TextView) view.findViewById(R.id.eat_times_text_view);

        /**
         * 找到各个内容的列标签
         */
        int numberColumnIndex=cursor.getColumnIndex(PetInforamtionDatabase.COLUMN_PET_INIT_NUMBER);
        int breedColumnIndex=cursor.getColumnIndex(PetInforamtionDatabase.COLUMN_PET_BRRED);
        int weightColumnIndex=cursor.getColumnIndex(PetInforamtionDatabase.COLUMN_PET_WEIGHT);
        int eatTimesColumnIndex=cursor.getColumnIndex(PetInforamtionDatabase.COLUMN_PET_EAT_TIMES);

        /**
         *读取对应标签的信息
         */
        int number=cursor.getInt(numberColumnIndex);
        String breed=cursor.getString(breedColumnIndex);
        int weight=cursor.getInt(weightColumnIndex);
        int eatTimes=cursor.getInt(eatTimesColumnIndex);

        /**
         * 设置显示Cursor中读取的内容
         */
        numberTextView.setText(String.valueOf(number));
        breedTextView.setText(breed);
        weightTextView.setText(String.valueOf(weight));
        eatTimesTextView.setText(String.valueOf(eatTimes));

    }

}

1.4 Activity对应的显示控件

显示控件

这里采用的是ListView用于显示。

代码
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.android.kimhlo.smartfeed.ui.EditPetInformationActivity">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/brief_information_list_view">
    </ListView>

    <!--当没有ListView没有内容显示的时候,显示如下内容-->
    <RelativeLayout
        android:id="@+id/brief_empty_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/empty_information"
            android:gravity="center"
            android:text="没有宠物信息,请加入宠物。"
            android:textSize="20sp"
            android:textColor="#A2AAB0"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/empty_information"
            android:text="点击右下角的浮动按钮添加"
            android:textSize="20sp"
            android:textColor="#A2AAB0"/>
    </RelativeLayout>
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/add_Pet_floating_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        app:srcCompat="@drawable/ic_add_white_24dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="30dp"
        android:layout_marginBottom="30dp"/>
</RelativeLayout>
XML结果

Android使用之CursorAdapter

1.5 在Activity中实现LoaderManager.LoaderCallbacks

实现该接口主要为了获得在content下对应projection的cursor,用于Adapter的创建。采用Loader的原因在于不必每次旋转屏幕的时候重新执行onCreate的时候都重新创建新的Curosr从而防止内存泄露等各种问题。

实现该接口就必须要实现三个子方法:

  • public Loader onCreateLoader(int id, Bundle args)
  • public void onLoadFinished(Loader loader, Cursor data)
  • public void onLoaderReset(Loader loader)

其中,onCreateLoader方法用于检测是否需要创建新的Loader,即不会每次都去创建新的curosr。onLoadFinished方法是当创建完成后的操作,有数据更改后用新的Cursor去更新BriefInformationAdapter。onLoaderReset是Loader重置后的操作,当数据需要被删除的时候回调该函数。

在onCreate函数中通过getLoaderManager().initLoader(PET_LOADER,null,this)来初始化Loader,PET_LOADER是该Loader的标号。(实现在1.6中代码部分见)

代码
//创建Loader
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {

    //在cursor中需要显示的信息
    String[] projection ={
            PetInforamtionDatabase._ID,
            PetInforamtionDatabase.COLUMN_PET_INIT_NUMBER,
            PetInforamtionDatabase.COLUMN_PET_WEIGHT,
            PetInforamtionDatabase.COLUMN_PET_HEAD_TEMPERATURE,
            PetInforamtionDatabase.COLUMN_PET_BODY_TEMPERATURE,
            PetInforamtionDatabase.COLUMN_PET_EAT_TIMES,
            PetInforamtionDatabase.COLUMN_PET_BRRED
    };

    //Loader将会在后台执行ContentProvider的query方法
    return new CursorLoader(
            this,//显示该信息的环境就是该Activity
            PetInforamtionDatabase.CONTENT_URI,//查询的地址
            projection,//查询的信息内容
            null,//没有选择的条件
            null,//没有选择的条件值
            null//默认的方式排序
    );
}

//载入Loader完成后
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    //用新的Cursor去更新{@link BriefInformationAdapter}
    mCursorAdapter.swapCursor(data);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    //当数据需要被删除的时候回掉
    mCursorAdapter.swapCursor(null);
}

1.6 在Activity中载入Adapter

相应控件载入Adapter

在对应的Activity中的onCreate函数中确定相应的显示控件,这里采用的是该Activity的XML中对应的ListView控件。找到相应的控件后用setAadapter方法设置实例化后的Adapter就可以完成显示

代码
public class EditPetInformationActivity extends AppCompatActivity
        implements LoaderManager.LoaderCallbacks<Cursor>{

    /**该Activity的Loader的编号**/
    private static final int PET_LOADER=0;

    /**ListView对应的适配器**/
    BriefInformationAdapter mCursorAdapter;


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

        //设置浮动按钮的触发Activity
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.add_Pet_floating_button);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent addPet=new Intent(EditPetInformationActivity.this,AddPetActivity.class);
                startActivity(addPet);
            }
        });

        //确定显示用来显示宠物详细信息的ListView
        ListView briefInformationListView=(ListView) findViewById(R.id.brief_information_list_view);

        View emptyView=findViewById(R.id.brief_empty_view);
        briefInformationListView.setEmptyView(emptyView);

        //设置Adapter
        mCursorAdapter=new BriefInformationAdapter(this,null);
        briefInformationListView.setAdapter(mCursorAdapter);

        //设置ListView的元素点击事件
        briefInformationListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //设置相应的Intent打开对应的Activity
                Intent openDetail=new Intent(EditPetInformationActivity.this,ItemDetailInformationActivity.class);
                //通过id去创建相应的Uri
                Uri mCurrentUri= ContentUris.withAppendedId(PetInforamtionDatabase.CONTENT_URI,id);
                //发送生成的Uri到Intent
                openDetail.setData(mCurrentUri);
                //打开相应的Activity
                startActivity(openDetail);
            }
        });

        getLoaderManager().initLoader(PET_LOADER,null,this);
    }
相关标签: android 控件