更改目录结构,增加拖动排序并更新数据库
This commit is contained in:
@@ -7,7 +7,6 @@ import androidx.lifecycle.Observer;
|
||||
|
||||
import com.ttstd.dialer.R;
|
||||
import com.ttstd.dialer.base.mvvm.BaseMvvmActivity;
|
||||
import com.ttstd.dialer.contact.Contact;
|
||||
import com.ttstd.dialer.databinding.ActivityContactAddBinding;
|
||||
import com.ttstd.dialer.filter.NoSpaceInputFilter;
|
||||
|
||||
@@ -58,8 +57,7 @@ public class ContactAddActivity extends BaseMvvmActivity<ContactAddViewModel, Ac
|
||||
public void save(View view) {
|
||||
String name = mViewDataBinding.etName.getText().toString();
|
||||
String phone = mViewDataBinding.etPhone.getText().toString();
|
||||
Contact contact = new Contact(name, phone);
|
||||
mViewModel.insert(contact);
|
||||
mViewModel.saveContact(name, phone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,21 @@ import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.ttstd.dialer.base.mvvm.BaseViewModel;
|
||||
import com.ttstd.dialer.contact.Contact;
|
||||
import com.ttstd.dialer.contact.ContactRepository;
|
||||
import com.ttstd.dialer.databinding.ActivityContactAddBinding;
|
||||
import com.ttstd.dialer.db.contact.Contact;
|
||||
import com.ttstd.dialer.db.contact.ContactRepository;
|
||||
|
||||
import java.util.List;
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class ContactAddViewModel extends BaseViewModel<ActivityContactAddBinding, ActivityEvent> {
|
||||
private static final String TAG = "ContactAddViewModel";
|
||||
@@ -25,9 +33,41 @@ public class ContactAddViewModel extends BaseViewModel<ActivityContactAddBinding
|
||||
|
||||
public MutableLiveData<Long> mIntegerMutableLiveData = new MutableLiveData<>();
|
||||
|
||||
public void insert(Contact contact) {
|
||||
Log.e(TAG, "insert: " );
|
||||
mIntegerMutableLiveData.setValue(mRepository.insert(contact));
|
||||
public void saveContact(String name, String phone) {
|
||||
Observable.create(new ObservableOnSubscribe<Long>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Long> emitter) throws Throwable {
|
||||
int count = mRepository.getTotalCount() + 1;
|
||||
Contact contact = new Contact(name, phone, count);
|
||||
Log.e(TAG, "saveContact: " + contact);
|
||||
emitter.onNext(mRepository.insert(contact));
|
||||
emitter.onComplete();
|
||||
}
|
||||
}).compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Long>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("saveContact", "onSubscribe: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Long aLong) {
|
||||
Log.e("saveContact", "onNext: " + aLong);
|
||||
mIntegerMutableLiveData.setValue(aLong);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("saveContact", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("saveContact", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,14 +7,13 @@ import android.view.View;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.ttstd.dialer.R;
|
||||
import com.ttstd.dialer.activity.contact.add.ContactAddActivity;
|
||||
import com.ttstd.dialer.adapter.ContactInfoAdapter;
|
||||
import com.ttstd.dialer.base.mvvm.BaseMvvmActivity;
|
||||
import com.ttstd.dialer.contact.Contact;
|
||||
import com.ttstd.dialer.databinding.ActivityContactListBinding;
|
||||
import com.ttstd.dialer.db.contact.Contact;
|
||||
import com.ttstd.dialer.view.ItemTouchHelperCallback;
|
||||
|
||||
import java.util.List;
|
||||
@@ -25,6 +24,8 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
|
||||
|
||||
private ContactInfoAdapter mContactInfoAdapter;
|
||||
|
||||
private List<Contact> mContacts;
|
||||
|
||||
@Override
|
||||
public boolean setNightMode() {
|
||||
return true;
|
||||
@@ -54,12 +55,21 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
|
||||
mContactInfoAdapter.setItemMoveCallback(new ContactInfoAdapter.ItemMoveCallback() {
|
||||
@Override
|
||||
public void onItemMove(int fromPosition, int toPosition) {
|
||||
Log.e(TAG, "onItemMove: " );
|
||||
Log.e(TAG, "onItemMove: ");
|
||||
Contact fromContact = mContacts.get(fromPosition);
|
||||
int fromContactPosition = fromContact.getPosition();
|
||||
Contact toContact = mContacts.get(toPosition);
|
||||
int toContactPosition = toContact.getPosition();
|
||||
fromContact.setPosition(toContactPosition);
|
||||
mViewModel.updateItemPosition(fromContact);
|
||||
toContact.setPosition(fromContactPosition);
|
||||
mViewModel.updateItemPosition(toContact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemRemoved(int position) {
|
||||
Log.e(TAG, "onItemRemoved: " );
|
||||
Log.e(TAG, "onItemRemoved: ");
|
||||
|
||||
}
|
||||
});
|
||||
// 设置ItemTouchHelper,实现拖动和滑动删除
|
||||
@@ -78,8 +88,9 @@ public class ContactListActivity extends BaseMvvmActivity<ContactListViewModel,
|
||||
mViewModel.mContactListData.observe(this, new Observer<List<Contact>>() {
|
||||
@Override
|
||||
public void onChanged(List<Contact> contacts) {
|
||||
Log.e(TAG, "onChanged: " + contacts);
|
||||
mContactInfoAdapter.setContacts(contacts);
|
||||
Log.e(TAG, "mContactListData: " + contacts);
|
||||
mContacts = contacts;
|
||||
mContactInfoAdapter.setContacts(mContacts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,18 +1,27 @@
|
||||
package com.ttstd.dialer.activity.contact.list;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.trello.rxlifecycle4.RxLifecycle;
|
||||
import com.trello.rxlifecycle4.android.ActivityEvent;
|
||||
import com.ttstd.dialer.base.mvvm.BaseViewModel;
|
||||
import com.ttstd.dialer.contact.Contact;
|
||||
import com.ttstd.dialer.contact.ContactRepository;
|
||||
import com.ttstd.dialer.databinding.ActivityContactListBinding;
|
||||
import com.ttstd.dialer.db.contact.Contact;
|
||||
import com.ttstd.dialer.db.contact.ContactRepository;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.rxjava3.annotations.NonNull;
|
||||
import io.reactivex.rxjava3.core.Observable;
|
||||
import io.reactivex.rxjava3.core.ObservableEmitter;
|
||||
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||
import io.reactivex.rxjava3.core.Observer;
|
||||
import io.reactivex.rxjava3.disposables.Disposable;
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||
|
||||
public class ContactListViewModel extends BaseViewModel<ActivityContactListBinding, ActivityEvent> {
|
||||
private static final String TAG = "ContactListViewModel";
|
||||
@@ -27,19 +36,81 @@ public class ContactListViewModel extends BaseViewModel<ActivityContactListBindi
|
||||
public MutableLiveData<List<Contact>> mContactListData = new MutableLiveData<>();
|
||||
|
||||
public void getAllContacts() {
|
||||
List<Contact> contacts = mRepository.getAllContacts();
|
||||
List<Contact> sorted = contacts.stream().sorted(new Comparator<Contact>() {
|
||||
Observable.create(new ObservableOnSubscribe<List<Contact>>() {
|
||||
@Override
|
||||
public int compare(Contact o1, Contact o2) {
|
||||
return Integer.compare(o1.getSort(), o2.getSort());
|
||||
public void subscribe(@NonNull ObservableEmitter<List<Contact>> emitter) throws Throwable {
|
||||
List<Contact> contacts = mRepository.getAllContacts();
|
||||
emitter.onNext(contacts);
|
||||
emitter.onComplete();
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
}).compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<List<Contact>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("getAllContacts", "onSubscribe: ");
|
||||
}
|
||||
|
||||
mContactListData.setValue(sorted);
|
||||
@Override
|
||||
public void onNext(@NonNull List<Contact> contacts) {
|
||||
Log.e("getAllContacts", "onNext: ");
|
||||
mContactListData.setValue(contacts);
|
||||
|
||||
// List<Contact> sorted = contacts.stream().sorted(new Comparator<Contact>() {
|
||||
// @Override
|
||||
// public int compare(Contact o1, Contact o2) {
|
||||
// return Integer.compare(o1.getSort(), o2.getSort());
|
||||
// }
|
||||
// }).collect(Collectors.toList());
|
||||
// mContactListData.setValue(sorted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("getAllContacts", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("getAllContacts", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Contact> searchContacts(String query) {
|
||||
return mRepository.searchContacts(query);
|
||||
public void updateItemPosition(Contact contact) {
|
||||
Log.e(TAG, "updateItemPosition: " + contact);
|
||||
Observable.create(new ObservableOnSubscribe<Integer>() {
|
||||
@Override
|
||||
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
|
||||
int id = mRepository.update(contact);
|
||||
emitter.onNext(id);
|
||||
emitter.onComplete();
|
||||
}
|
||||
}).compose(RxLifecycle.bindUntilEvent(getLifecycle(), ActivityEvent.DESTROY))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<Integer>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
Log.e("updateItemPosition", "onComplete: ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull Integer integer) {
|
||||
Log.e("updateItemPosition", "onNext: " + integer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
Log.e("updateItemPosition", "onError: " + e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Log.e("updateItemPosition", "onComplete: ");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.shehuan.niv.NiceImageView;
|
||||
import com.ttstd.dialer.R;
|
||||
import com.ttstd.dialer.contact.Contact;
|
||||
import com.ttstd.dialer.db.contact.Contact;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -81,6 +81,9 @@ public class ContactInfoAdapter extends RecyclerView.Adapter<ContactInfoAdapter.
|
||||
}
|
||||
}
|
||||
notifyItemMoved(fromPosition, toPosition);
|
||||
if (mItemMoveCallback != null) {
|
||||
mItemMoveCallback.onItemMove(fromPosition, toPosition);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理滑动删除
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.ttstd.dialer.contact;
|
||||
package com.ttstd.dialer.db.contact;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -19,8 +20,8 @@ public abstract class AppDatabase extends RoomDatabase {
|
||||
synchronized (AppDatabase.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||
AppDatabase.class, context.getExternalCacheDir() + File.separator +"contact_database")
|
||||
.allowMainThreadQueries() // 为了简化示例,允许主线程查询
|
||||
AppDatabase.class, context.getExternalFilesDir("db") + File.separator + "contact_database")
|
||||
// .allowMainThreadQueries() // 为了简化示例,允许主线程查询
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.ttstd.dialer.contact;
|
||||
package com.ttstd.dialer.db.contact;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -19,12 +19,13 @@ public class Contact implements Serializable {
|
||||
private String name;
|
||||
private String phoneNumber;
|
||||
private String avatar;
|
||||
private int sort;
|
||||
private String wxid;
|
||||
private int position;
|
||||
|
||||
public Contact(String name, String phoneNumber) {
|
||||
public Contact(String name, String phoneNumber, int position) {
|
||||
this.name = name;
|
||||
this.phoneNumber = phoneNumber;
|
||||
this.sort = 0;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
@@ -59,12 +60,20 @@ public class Contact implements Serializable {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
public String getWxid() {
|
||||
return wxid;
|
||||
}
|
||||
|
||||
public void setSort(int sort) {
|
||||
this.sort = sort;
|
||||
public void setWxid(String wxid) {
|
||||
this.wxid = wxid;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.ttstd.dialer.contact;
|
||||
package com.ttstd.dialer.db.contact;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
@@ -10,6 +10,14 @@ import java.util.List;
|
||||
|
||||
@Dao
|
||||
public interface ContactDao {
|
||||
// 基本查询:获取总行数
|
||||
@Query("SELECT COUNT(*) FROM contacts")
|
||||
int getTotalCount();
|
||||
|
||||
// 查询:根据特定列的非空值计数
|
||||
@Query("SELECT COUNT(id) FROM contacts")
|
||||
int getCountById();
|
||||
|
||||
@Insert
|
||||
long insert(Contact contact);
|
||||
|
||||
@@ -25,7 +33,7 @@ public interface ContactDao {
|
||||
@Query("DELETE FROM contacts")
|
||||
int deleteAll();
|
||||
|
||||
@Query("SELECT * FROM contacts ORDER BY name ASC")
|
||||
@Query("SELECT * FROM contacts ORDER BY position ASC")
|
||||
List<Contact> getAllContacts();
|
||||
|
||||
@Query("SELECT * FROM contacts WHERE id = :id")
|
||||
@@ -1,17 +1,24 @@
|
||||
package com.ttstd.dialer.contact;
|
||||
package com.ttstd.dialer.db.contact;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContactRepository {
|
||||
private ContactDao mContactDao;
|
||||
private List<Contact> mAllContacts;
|
||||
|
||||
// 构造函数,获取数据库访问对象
|
||||
public ContactRepository(Context context) {
|
||||
AppDatabase db = AppDatabase.getDatabase(context);
|
||||
mContactDao = db.contactDao();
|
||||
mAllContacts = mContactDao.getAllContacts();
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return mContactDao.getTotalCount();
|
||||
}
|
||||
|
||||
public int getCountById() {
|
||||
return mContactDao.getCountById();
|
||||
}
|
||||
|
||||
// 获取所有联系人
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.ttstd.dialer.contact;
|
||||
package com.ttstd.dialer.db.contact;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ContactViewModel extends AndroidViewModel {
|
||||
@@ -29,7 +29,7 @@ public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
|
||||
RecyclerView.ViewHolder target) {
|
||||
// 通知适配器项已移动
|
||||
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
|
||||
mAdapter.onItemMove(viewHolder.getBindingAdapterPosition(), target.getBindingAdapterPosition());
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
// 通知适配器项已删除
|
||||
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
|
||||
mAdapter.onItemDismiss(viewHolder.getBindingAdapterPosition());
|
||||
}
|
||||
|
||||
// 当长按item时启用拖动
|
||||
@@ -49,6 +49,6 @@ public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||
// 启用滑动删除
|
||||
@Override
|
||||
public boolean isItemViewSwipeEnabled() {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user