Перетащите RecyclerView, который заполняется из SQLiteDatabaseAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Перетащите RecyclerView, который заполняется из SQLiteDatabase

Сообщение Anonymous »

Информация:
У меня есть RecyclerView, и я заполняю его с помощью ArrayList dataList внутри класса ListAdapter. Я получаю данные для dataList из таблицы SQLiteDatabase: TABLE_USERdETAIL в классе DbHelper. Я пытаюсь реализовать реорганизацию перетаскивания в RecyclerView с помощью класса SimpleItemTouchHelperCallback; однако, хотя теперь я могу перемещать элементы RecyclerView, список не пересортировывается и не перемещается; Я могу только временно перетаскивать элементы списка друг на друга, как показано на изображении ниже, но это означает постоянное размещение элементов списка в любом положении:
Я ожидаю, что проблема будет внутри класса ListAdapter, внутри метода onItemMove, но я не знаю, как решить мою проблему.
Вопрос: Как мне реализовать эту функцию перетаскивания действительно реорганизовать список данных RecyclerView?
Обновление 5: Я обновил свой текущий код для получения дополнительной помощи.
Класс ListAdapter
public class ListAdapter extends RecyclerView.Adapter {

Context context;
List dataList = new ArrayList();
LayoutInflater inflater;
Listener listener;
DbHelper dbHelper;

public interface Listener {
void nameToChnge(String name);
}

public ListAdapter(Context context, List dataList1) {
this.context = context;
this.dataList = dataList1;
//this.listener= (Listener) context;
inflater = LayoutInflater.from(context);
}

@Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View convertView = inflater.inflate(R.layout.recylerview_one, parent, false);
ListViewHolder viewHolder = new ListViewHolder(convertView);
return viewHolder;
}

@Override
public void onBindViewHolder(ListViewHolder holder, final int position) {
holder.tv_name.setText(dataList.get(position).name);
holder.tv_quantity.setText(dataList.get(position).quantity);
holder.tv_description.setText(dataList.get(position).description + " ");

if(dataList.get(position).description.isEmpty()) {
holder.tv_description.setVisibility(View.GONE);
}

holder.relLayout.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
String s = dataList.get(position).id;
Integer stringo = Integer.parseInt(s);
Intent intent = new Intent(context, ItemEditActivity.class);
intent.putExtra("ItemNumber", stringo);
context.startActivity(intent);
}
});
}

@Override
public int getItemCount() {
return dataList.size();
}

class ListViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
TextView tv_name, tv_quantity, tv_description;
RelativeLayout relLayout;

public ListViewHolder(View itemView) {
super(itemView);
tv_name = (TextView) itemView.findViewById(R.id.nameDisplay);
tv_quantity = (TextView) itemView.findViewById(R.id.quantityDisplay);
tv_description = (TextView) itemView.findViewById(R.id.descriptionDisplay);
relLayout = (RelativeLayout) itemView.findViewById(R.id.relLayout);
}
@Override
public void onItemSelected() {
Log.d("ListViewHolder", "item selected");
}

@Override
public void onItemClear() {
Log.d("ListViewHolder", "item clear");
for (int count = 0; count < dataList.size(); count++) {
UserData u = dataList.get(count);
u.setSort(count);
dbHelper.updateUserData(u);
}
notifyDataSetChanged();
}
}

public void onItemDismiss(int position) {
dataList.remove(position);
//dbHelper = DbHelper.getInstance(context);
//dbHelper.deleteRowItem(position + 1);
notifyItemRemoved(position);
}

//Collections.swap(dataList, fromPosition, toPosition);
//notifyItemMoved(fromPosition, toPosition);

public boolean onItemMove(int fromPosition, int toPosition) {
if (fromPosition < toPosition) {
for (int i = fromPosition; i < toPosition; i++) {
Collections.swap(dataList, i, i + 1);
}
} else {
for (int i = fromPosition; i > toPosition; i--) {
Collections.swap(dataList, i, i - 1);
}
}
notifyItemMoved(fromPosition, toPosition);
return true;
}
}

Класс SimpleItemTouchHelperCallback
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
private final ListAdapter mAdapter;

public SimpleItemTouchHelperCallback(ListAdapter adapter) {
mAdapter = adapter;
}

@Override
public boolean isLongPressDragEnabled() {return true; }

@Override
public boolean isItemViewSwipeEnabled() { return false; }

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}

@Override
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
RecyclerView.ViewHolder target) {
mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
return true;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
// We only want the active item to change
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Let the view holder know that this item is being moved or dragged
Log.i("ADAPTER", "----DRAGGING----");
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemSelected();
}
}

super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);

if (viewHolder instanceof ItemTouchHelperViewHolder) {
// Tell the view holder it's time to restore the idle state
ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
itemViewHolder.onItemClear();
}
}
}

Класс DbHelper
public class DbHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "UserDatabase";
private static final int DATABASE_VERSION = 2;
private static DbHelper mDbHelper;

public static String TABLE_USERdETAIL = "userdetail";

private static final String _ID = "_id";
private static final String SORT_ID = "sort_id";
private static final String NAME = "name";
private static final String QUANTITY = "quantity";
private static final String WEIGHT = "weight";
private static final String WEIGHTTOTAL = "weighttotal";
private static final String VALUE = "value";
private static final String VALUETOTAL = "valuetotal";
private static final String DESCRIPTION = "description";

public static synchronized DbHelper getInstance(Context context) {
if (mDbHelper == null) {
mDbHelper = new DbHelper(context.getApplicationContext());
}
return mDbHelper;
}

public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {

String CREATE_USERDETAIL_TABLE = "CREATE TABLE " + TABLE_USERdETAIL +
"(" +
_ID + " INTEGER PRIMARY KEY , " +
SORT_ID + " INTEGER," +
NAME + " TEXT," +
QUANTITY + " INTEGER," +
WEIGHT + " INTEGER," +
WEIGHTTOTAL + " INTEGER," +
VALUE + " INTEGER," +
VALUETOTAL + " INTEGER," +
DESCRIPTION + " TEXT" +
")";

db.execSQL(CREATE_USERDETAIL_TABLE);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion != newVersion) {
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + WEIGHT + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + WEIGHTTOTAL + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + VALUE + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + TABLE_USERdETAIL + " ADD COLUMN " + VALUETOTAL + " INTEGER DEFAULT 0");
}
}

/**
Insert a user detail into database
*/
public void insertUserDetail(UserData userData) {

SQLiteDatabase db = getWritableDatabase();

db.beginTransaction();

try {
ContentValues values = new ContentValues();
values.put(SORT_ID, userData.sort_id);
values.put(NAME, userData.name);
values.put(QUANTITY, userData.quantity);
values.put(WEIGHT, userData.weight);
values.put(WEIGHTTOTAL, userData.weighttotal);
values.put(VALUE, userData.value);
values.put(VALUETOTAL, userData.valuetotal);
values.put(DESCRIPTION, userData.description);

db.insertOrThrow(TABLE_USERdETAIL, null, values);
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}

}

public void updateUserDetail(int id, String v1, String v2, String v3, String v4, String v5, String v6, String v7){
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();
values.put(NAME, v1);
values.put(QUANTITY, v2);
values.put(DESCRIPTION, v3);
values.put(WEIGHT, v4);
values.put(WEIGHTTOTAL, v5);
values.put(VALUE, v6);
values.put(VALUETOTAL, v7);
db.update(TABLE_USERdETAIL, values, "_id="+id, null);
}

/**
fetch all data from UserTable
*/
public List getAllUser() {
List usersdetail = new ArrayList();

String USER_DETAIL_SELECT_QUERY = "SELECT * FROM " + TABLE_USERdETAIL + " ORDER BY " + SORT_ID + " COLLATE NOCASE;";

SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(USER_DETAIL_SELECT_QUERY, null);

try {
if (cursor.moveToFirst()) {
do {
UserData userData = new UserData();
userData.id = cursor.getString(cursor.getColumnIndex(_ID));
userData.sort_id = cursor.getInt(cursor.getColumnIndex(SORT_ID));
userData.name = cursor.getString(cursor.getColumnIndex(NAME));
userData.quantity = "Quantity: " + cursor.getString(cursor.getColumnIndex(QUANTITY));
userData.weight = cursor.getString(cursor.getColumnIndex(WEIGHT));
userData.weighttotal = cursor.getString(cursor.getColumnIndex(WEIGHTTOTAL));
userData.value = cursor.getString(cursor.getColumnIndex(VALUE));
userData.valuetotal = cursor.getString(cursor.getColumnIndex(VALUETOTAL));
userData.description = cursor.getString(cursor.getColumnIndex(DESCRIPTION));

usersdetail.add(userData);
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return usersdetail;

}

/**
Delete single row from UserTable
*/
void deleteRow(String name) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
db.execSQL("delete from " + TABLE_USERdETAIL + " where name ='" + name + "'");
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}

void deleteRowItem(int id) {
SQLiteDatabase db = getWritableDatabase();
try {
db.beginTransaction();
db.execSQL("delete from " + TABLE_USERdETAIL + " where _id ='" + id + "'");
db.setTransactionSuccessful();
} catch (SQLException e) {
e.printStackTrace();
} finally {
db.endTransaction();
}
}

public UserData getSingleUserDetail(String userId) {
SQLiteDatabase db = this.getWritableDatabase();
UserData userData = null;

//Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_USERdETAIL, null);

// this is the code to order the RecyclerView by _ID:
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_USERdETAIL + " WHERE " + _ID + "= ?", new String[]{userId});
try {
while (cursor.moveToNext()) {
userData = new UserData();
userData.name = cursor.getString(cursor.getColumnIndex(NAME));
userData.quantity = cursor.getString(cursor.getColumnIndex(QUANTITY));
userData.weight = cursor.getString(cursor.getColumnIndex(WEIGHT));
userData.weighttotal = cursor.getString(cursor.getColumnIndex(WEIGHTTOTAL));
userData.value = cursor.getString(cursor.getColumnIndex(VALUE));
userData.valuetotal = cursor.getString(cursor.getColumnIndex(VALUETOTAL));
userData.description = cursor.getString(cursor.getColumnIndex(DESCRIPTION));
}
cursor.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return userData;
}

public int getTotalWeight() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(WEIGHTTOTAL) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalWeight();
}

public int getTotalQuantity() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(QUANTITY) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalQuantity();
}

public int getTotalValue() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cur = db.rawQuery("SELECT SUM(VALUETOTAL) FROM userdetail", null);
if(cur.moveToFirst())
{
return cur.getInt(0);
}
cur.close();
return getTotalValue();
}

public int getMaxColumnData() {
SQLiteDatabase db = this.getWritableDatabase();
final SQLiteStatement stmt = db
.compileStatement("SELECT MAX(SORT_ID) FROM " + TABLE_USERdETAIL);

return (int) stmt.simpleQueryForLong();
}

public void updateUserData(UserData userData) {

SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();

values.put(NAME, userData.getName());
values.put(QUANTITY, userData.getQuantity());
values.put(DESCRIPTION, userData.getDescription());
values.put(WEIGHT, userData.getWeight());
values.put(WEIGHTTOTAL, userData.getWeighttotal());
values.put(VALUE, userData.getValue());
values.put(VALUETOTAL, userData.getValuetotal());
values.put(SORT_ID, userData.getSort());

Log.i("DBhelper", "USER UPDATED = " + userData.getName());

db.update(TABLE_USERdETAIL, values, _ID + "=?", new String[]{String.valueOf(userData.getId())});

}
}

Класс UserData
import java.io.Serializable;

public class UserData implements Serializable {
String id, name, quantity, weight, weighttotal, value, valuetotal, description;
int sort_id;

public UserData() {
super();
}

public void setId(String id){
this.id= id;
}
public String getId(){
return id;
}
public void setSort(int sort){
this.sort_id= sort;
}
public int getSort(){
return sort_id;
}

public void setName(String name){
this.name= name;
}
public String getName(){
return name;
}
public void setDescription(String description){
this.description= description;
}
public String getDescription(){
return description;
}
public void setQuantity(String quantity){
this.quantity= quantity;
}
public String getQuantity(){
return quantity;
}
public void setWeight(String weight){
this.weight= weight;
}
public String getWeight(){
return weight;
}
public void setWeighttotal(String weighttotal){
this.weighttotal= weighttotal;
}
public String getWeighttotal(){
return weighttotal;
}
public void setValue(String value){
this.value= value;
}
public String getValue(){
return value;
}
public void setValuetotal(String valuetotal){
this.quantity= valuetotal;
}
public String getValuetotal(){
return quantity;
}
}

Класс ItemTouchHelperViewHolder
public interface ItemTouchHelperViewHolder {
void onItemSelected();
void onItemClear();
}

Класс MainActivity
public class MainActivity extends AppCompatActivity implements ListAdapter.Listener {

RecyclerView recyclerView;
DbHelper dbHelper;
ListAdapter adapter;
private ItemTouchHelper mItemTouchHelper;

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

dbHelper = DbHelper.getInstance(getApplicationContext());

recyclerView = (RecyclerView) findViewById(R.id.rv_contactlist);
adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

ItemTouchHelper.Callback callback =
new SimpleItemTouchHelperCallback(adapter);
mItemTouchHelper = new ItemTouchHelper(callback);
mItemTouchHelper.attachToRecyclerView(recyclerView);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.about_task:
Intent intentChangeActivity2 = new Intent(MainActivity.this, AboutActivity.class);
startActivity(intentChangeActivity2);
return true;
case R.id.encumbrance_task:
Intent intentChangeActivity = new Intent(MainActivity.this, EncumbranceActivity.class);
startActivity(intentChangeActivity);
return true;
default:
return super.onOptionsItemSelected(item);
}
}

@Override
public void onResume() {
super.onResume();
dbHelper = DbHelper.getInstance(getApplicationContext());

recyclerView = (RecyclerView) findViewById(R.id.rv_contactlist);
adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

}

@Override
public void nameToChnge(String name) {
dbHelper.deleteRow(name);

adapter = new ListAdapter(this, dbHelper.getAllUser());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}

}

Журнал ошибок:
8-26 11:20:49.443 23533-23533/name.appE/AndroidRuntime: FATAL EXCEPTION: main
Process: name.app, PID: 23533
java.lang.NullPointerException: Attempt to invoke virtual method 'void name.app.DbHelper.updateUserData(name.app.UserData)' on a null object reference
at name.app.ListAdapter$ListViewHolder.onItemClear(ListAdapter.java:95)
at name.app.SimpleItemTouchHelperCallback.clearView(SimpleItemTouchHelperCallback.java:63)
at android.support.v7.widget.helper.ItemTouchHelper$3.onAnimationEnd(ItemTouchHelper.java:619)
at android.support.v4.animation.HoneycombMr1AnimatorCompatProvider$AnimatorListenerCompatWrapper.onAnimationEnd(HoneycombMr1AnimatorCompatProvider.java:115)
at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1149)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1309)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
at android.animation.AnimationHandler.-wrap2(AnimationHandler.java)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:869)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:616)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)


Подробнее здесь: https://stackoverflow.com/questions/418 ... tedatabase
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»