之前学习Android时,照着《第一行代码》的例子敲了一边,实际开发时,需求并不是提供数据库中的数据,而是应用中的一个list或者一个String类型状态信息,当时反而不知道该如何将这些信息包装到cursor中,后面学习了MatrixCursor,解决了当时的问题,现在编写了一个例子回顾一下:
在《第一行代码》的第三章,有个关于水果的RecyclerView例子,在其基础上做点修改,之前例子显示的数据是在初始化函数中进行初始化,如下:
public void intFruit(){
Fruit apple = new Fruit(R.drawable.apple_pic ,"apple");
mFruitsList.add(apple);
Fruit banana = new Fruit(R.drawable.banana_pic ,"banana");
mFruitsList.add(banana);
Fruit cherry = new Fruit(R.drawable.cherry_pic ,"cherry");
mFruitsList.add(cherry);
}
我们现在将该方法注掉,用另一个应用ContentProviderApplication来提供RecyclerView显示所需要的数据。以下是该应用中新建的内容提供器,使用MatrixCursor建立一个虚表,返回一个cursor,COLUM_NAME 是表的列名,一张图片、一个水果名称。fruitList.addAll(MainActivity.mFruitList);是将MainActivty中初始化的水果列表获取。
public class FruitContentProvider extends ContentProvider {
private static final String[] COLUM_NAME = {"drawable", "name"};
private static MatrixCursor matrixCursor;
private static ArrayList fruitList = new ArrayList();
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
fruitList.clear();
fruitList.addAll(MainActivity.mFruitList);
matrixCursor = new MatrixCursor(COLUM_NAME);
if (fruitList.size() > 0){
for (Fruit fruit: fruitList ) {
matrixCursor.addRow(new Object[]{fruit.getImageId(), fruit.getFruitName()});
}
}
return matrixCursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public boolean onCreate() {
return false;
}
public FruitContentProvider() {
}
}
ContentProviderApplication中的MainActivty,在这里初始化数据,并显示一个按钮add_fruit,点击按钮会修改mFruitList列表中的内容,并通知RecyclerView进行刷新显示。
public class MainActivity extends AppCompatActivity {
public static ArrayList mFruitList = new ArrayList<>();
public static String authorities = "content://com.example.contentproviderapplication";
private Button addButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addButton = findViewById(R.id.add_button);
addButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
addFruit();
getContentResolver().notifyChange(Uri.parse(authorities),null);
}
});
intFruit();
}
public void intFruit(){
Fruit apple = new Fruit(R.drawable.apple_pic ,"apple");
mFruitList.add(apple);
Fruit banana = new Fruit(R.drawable.banana_pic ,"banana");
mFruitList.add(banana);
Fruit cherry = new Fruit(R.drawable.cherry_pic ,"cherry");
mFruitList.add(cherry);
}
public void addFruit(){
Fruit grape = new Fruit(R.drawable.grape_pic ,"grape");
mFruitList.add(grape);
Fruit mango = new Fruit(R.drawable.mango_pic ,"mango");
mFruitList.add(mango);
Fruit orange = new Fruit(R.drawable.orange_pic ,"orange");
mFruitList.add(orange);
}
}
下面是RecyclerViewTest项目中的核心代码:在点击ContentProviderApplication中的按钮时,注册的onChange()回调会执行,可在该函数中重新查询数据,进行刷新显示。
public class MainActivity extends AppCompatActivity implements RecyclerViewItemStateListener{
private static final String TAG = "MainActivity";
private ArrayList mFruitsList = new ArrayList<>();
private RecyclerView mFruitRecycler;
public static String authorities = "content://com.example.contentproviderapplication";
private static final String[] COLUM_NAME = {"drawable", "name"};
private Handler mHandler;
private FruitAdapter mFruitAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFruitRecycler = findViewById(R.id.recycler_view);
//intFruit();
getFruitList();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mFruitRecycler.setLayoutManager(linearLayoutManager);
mFruitAdapter = new FruitAdapter(mFruitsList);
mFruitAdapter.setRecyclerViewItemStateListener(this);
mFruitRecycler.setAdapter(mFruitAdapter);
getContentResolver().registerContentObserver(Uri.parse(authorities),
true, new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.d(TAG, "onChange: ");
getFruitList();
mFruitAdapter.notifyDataSetChanged();
}
});
}
public void getFruitList(){
mFruitsList.clear();
Cursor cursor = getContentResolver().query(Uri.parse(authorities),COLUM_NAME,
null,null);
if(cursor != null){
while (cursor.moveToNext()){
int drawable = cursor.getInt(cursor.getColumnIndex(COLUM_NAME[0]));
String name = cursor.getString(cursor.getColumnIndex(COLUM_NAME[1]));
Fruit fruit = new Fruit(drawable, name);
mFruitsList.add(fruit);
}
}
}
public void intFruit(){
Fruit apple = new Fruit(R.drawable.apple_pic ,"apple");
mFruitsList.add(apple);
Fruit banana = new Fruit(R.drawable.banana_pic ,"banana");
mFruitsList.add(banana);
Fruit cherry = new Fruit(R.drawable.cherry_pic ,"cherry");
mFruitsList.add(cherry);
}
@Override
public void onItemClicked(RecyclerView.ViewHolder holder, View view, int position) {
Toast.makeText(this, "clicked the item", Toast.LENGTH_SHORT).show();
}
}
例子写的很简单(水平有限),目的就是再熟悉下ContentProvider和MatrixCursor的用法。
参考链接:https://blog.csdn.net/yelangjueqi/article/details/21232659