如何使用ActiveAndroid ORM来填充RecyclerView并跟踪数据更改是首选的方法?
我最近提出了一个问题,但它变得太冗长了,人们非常懒惰,几乎没有人会读到最后。
其实质是:有人有通过ActiveAndroid从数据库填充RecyclerView的工作示例吗?
如何使用ActiveAndroid ORM来填充RecyclerView并跟踪数据更改是首选的方法?
我最近提出了一个问题,但它变得太冗长了,人们非常懒惰,几乎没有人会读到最后。
其实质是:有人有通过ActiveAndroid从数据库填充RecyclerView的工作示例吗?
我使用EventBus来通知我的RecyclerView适配器,每当我向数据库添加数据时。
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final String TAG = "MainActivity";
private EditText etName, etAge;
private Button btnAdd;
private EventBus bus = EventBus.getDefault();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//declare all views
etName = (EditText) findViewById(R.id.et_name);
etAge = (EditText) findViewById(R.id.et_age);
btnAdd = (Button) findViewById(R.id.btn_add);
//add onClickListener to button
btnAdd.setOnClickListener(this);
android.support.v4.app.FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, ListFragment.newInstance());
transaction.commit();
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.btn_add:
PersonModel personModel = new PersonModel();
if (isEmpty(etName) || isEmpty(etAge)) {
Toast.makeText(this, "Please fill in all details", Toast.LENGTH_LONG).show();
} else {
personModel.name = etName.getText().toString();
personModel.age = etAge.getText().toString();
//Save data to database
personModel.save();
//Broadcast the event to notify fragment
bus.post("NOTIFY");
}
break;
default:
Log.e(TAG, "Invalid view ID");
break;
}
}
//Check edit text whether is empty or not
private boolean isEmpty(EditText etText) {
return etText.getText().toString().trim().length() == 0;
}
}
PersonModel.java
@Table(name = "PersonModel")
public class PersonModel extends Model {
@Column(name = "NAME")
public String name;
@Column(name = "AGE")
public String age;
}
PersonAdapter.java
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.MyViewHolder> {
private Context mContext;
private List<PersonModel> models;
public PersonAdapter(Context context, List<PersonModel> models) {
this.mContext = context;
this.models = models;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name, age;
public MyViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
age = (TextView) itemView.findViewById(R.id.age);
}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.person_cell, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
PersonModel personModel = models.get(position);
holder.name.setText(personModel.name);
holder.age.setText(personModel.age);
}
@Override
public int getItemCount() {
return models.size();
}
}
ListFragment.java
public class ListFragment extends Fragment {
private final String TAG = "ListFragment";
private EventBus bus = EventBus.getDefault();
private List<PersonModel> models = new ArrayList<PersonModel>();
private Context mContext;
private RecyclerView recyclerView;
private PersonAdapter personAdapter;
public static ListFragment newInstance() {
// Required empty public constructor
ListFragment listFragment = new ListFragment();
return listFragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
bus.register(this);
recyclerView = (RecyclerView) rootView.findViewById(R.id.list_rv);
//Load and add all data from database to array list
models = getAll();
personAdapter = new PersonAdapter(mContext, models);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(mContext);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(personAdapter);
personAdapter.notifyDataSetChanged();
return rootView;
}
//Load all data from database
private List<PersonModel> getAll() {
return new Select()
.all()
.from(PersonModel.class)
.orderBy("NAME ASC")
.execute();
}
//Load the last data added to database
private List<PersonModel> getLast() {
return new Select()
.all()
.from(PersonModel.class)
.orderBy("NAME DESC")
.limit(1)
.execute();
}
//Subscribe to event bus
//Receive notification/event from MainActivity when added a data to database
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(String STATUS) {
switch (STATUS) {
case "NOTIFY":
//Add last added item to current array list
models.add(getLast().get(0));
//refresh recyclerView's adapter
personAdapter.notifyDataSetChanged();
break;
default:
Log.e(TAG, "Invalid STATUS");
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.mContext = context;
}
}
可以使用模式来实现这个功能。使用BroadcastReceiver在数据库发生更改时通知您的活动(只需向您的活动发送显式意图并实现activity.onNewIntent())。
使用LocalBroadcastManager在将更改添加到数据库后向您的BroadCastReceiver发送广播。希望这可以帮助您。
我曾经使用过这个库,但是在 ListView
中使用。我想这段代码应该可以在 RecyclerView
中使用:
/* The database */
@Table(name = "Person")
public class Person extends Model {
@Column(name = "Name")
public String name;
@Column(name = "Age")
public int age;
}
/* Your MainActivity */
List<Person> list = new ArrayList<>();
private RecyclerView rv;
/* Activity onCreate */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
list = getList(15);
rv = (RecyclerView) findViewById(R.id.recycler_view);
rv.setLayoutManager(new LinearLayoutManager(this));
rv.setAdapter(new Adapter());
}
private List<Person> getList(int age){
return new Select()
.from(Person.class)
.where("Age = ?", age)
.orderBy(/* order you like */)
.executeSingle();
}
private class Adapter extends RecyclerView.Adapter<Adapter.Holder> {
@Override
public Adapter onCreateViewHolder(ViewGroup parent, int viewType) {
// you should inflate the layout you want be laid in every row of the recycler view. Im just inflating a text view for convinence
return new Holder(LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false));
}
@Override
public void onBindViewHolder(Holder holder, int position) {
// assign values to all view in the holder.
holder.tv.setText(list.get(position).name);
}
@Override
public int getItemCount() {
return list.size();
}
public class Holder extends RecyclerView.ViewHolder {
// here you load all the view in your layout
TextView tv;
public Holder(View itemView) {
super(itemView);
tv = (TextView) itemView;
}
}
}
在这里,我假设您已经创建并存储了数据库中的值,因为问题只要求从数据库填充。
我还没有测试过它,但我认为它应该可以工作。
RecyclerView
,还涉及到将视图绑定到数据集并观察其变化。因此,当数据集发生变化时,视图会自动收到通知。 - naXa stands with Ukraine