问题
I am trying to change the position of the RecyclerView
this take changes but if I go to another Activity
or exit the app and again open it, it tells me the right position.
The data are saved to an DB SDQLite
and with Adapter
I read from there and show to a Fragment
.
onMove
I have write a Log
and it says the correct which position was and which is new.
At the Log
the arrayList = getSampleData()
it is working it saves always the position and read the actual position but the ArrayList
at Fragment
now is hidden it doesn't show me anything.
At the first time it shows normally all items but when I change position then items are hidden and if I make arrayList.add(customer)
then shows me the data but are not sorted.
I use Collections.swap
for changing positions.
Here is the video so you can see what is happening.
https://streamable.com/fdyyy
Below is my code.
Fragment.class
public class SpeedDialFragment extends Fragment {
ArrayList<Bookmark> arrayList = new ArrayList<>();
AdapterForBookmark myAdapter;
List<Bookmark> test;
View paramView;
RecyclerView myRecyclerView;
BookmarkDB mDB;
private Context mContext;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
public static final String LIST_OF_SORTED_DATA_ID = "json_list_sorted_data_id";
public final static String PREFERENCE_FILE = "preference_file";
private ItemTouchHelper mItemTouchHelper;
public OnCustomerListChangedListener mListChangedListener;
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
mDB = new BookmarkDB(mContext);
mDB.getAllBookmarks();
buildBookmarkArrayListfromDB();
loadBookMarksFromXML();
}
@Nullable
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
paramView = inflater.inflate(R.layout.bookmark, container, false);
myRecyclerView = paramView.findViewById(R.id.myRecyclerView);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setHasFixedSize(true);
myAdapter = new AdapterForBookmark(mContext, arrayList);
final Bookmark bookmark = new Bookmark();
mSharedPreferences = getActivity()
.getSharedPreferences(PREFERENCE_FILE, Context.MODE_PRIVATE);
mEditor = mSharedPreferences.edit();
// arrayList.add(bookmark);
arrayList = getSampleData();
mListChangedListener = new OnCustomerListChangedListener() {
@Override
public void onNoteListChanged(ArrayList<Bookmark> bookmarkList) {
ArrayList<String> listOfSortedCustomerId = new ArrayList<String>();
for (Bookmark customer: arrayList){
listOfSortedCustomerId.add(customer.getId());
}
// convert the List of Longs to a JSON string
Gson gson = new Gson();
String jsonListOfSortedCustomerIds = gson.toJson(listOfSortedCustomerId);
// save to SharedPreference
mEditor.putString(LIST_OF_SORTED_DATA_ID, jsonListOfSortedCustomerIds).apply();
mEditor.apply();
}
};
myRecyclerView.setAdapter(myAdapter);
Log.d("TAG", "onCreateView: " + getSampleData());
ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
int position_dragged = viewHolder.getAdapterPosition();
int position_target = viewHolder1.getAdapterPosition();
long id = viewHolder.getItemId();
Collections.swap(arrayList, position_dragged, position_target);
myAdapter.notifyItemMoved(position_dragged, position_target);
mListChangedListener.onNoteListChanged(arrayList);
mDB.updateOrder(id, position_target);
SharedPreferences sharedPreferences = mContext.getSharedPreferences("OrderItems", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("item_positon", position_target);
editor.apply();
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
}
@Override
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
assert viewHolder != null;
viewHolder.itemView.setBackgroundColor(Color.parseColor("#30000000"));
}
super.onSelectedChanged(viewHolder, actionState);
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
viewHolder.itemView.setBackgroundColor(getResources().getColor(R.color.white));
super.clearView(recyclerView, viewHolder);
}
});
helper.attachToRecyclerView(myRecyclerView);
return paramView;
}
private void loadBookMarksFromXML() {
// MAY WISH TO ONLY DO THIS ONCE as bookmarks would be loaded OTHERWISE DELETE LINE BELOW
if (DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(), BookmarkDB.TBL_BOOKMARK) > 0)
return;
try {
XmlResourceParser xpp = getResources().getXml(R.xml.bookmarks);
while (xpp.getEventType() != XmlPullParser.END_DOCUMENT) {
if (xpp.getEventType() == XmlPullParser.START_TAG) {
if (xpp.getName().equals("Bookmark")) {
Bookmark bookmark = new Bookmark();
bookmark.setName(xpp.getAttributeValue(null, "name"));
bookmark.setSearchUrl(xpp.getAttributeValue(null, "searchUrl"));
bookmark.setNativeUrl(xpp.getAttributeValue(null, "nativeUrl"));
bookmark.setId(xpp.getAttributeValue(null, "id"));
int drawableResourceId = getResources().getIdentifier(xpp.getAttributeValue(null, "icon"), "drawable", mContext.getPackageName());
bookmark.setIcon(drawableResourceId);
bookmark.setViewType(0);
}
}
xpp.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void buildBookmarkArrayListfromDB() {
arrayList.clear();
arrayList.addAll(mDB.getAllBookmarks());
/* Bookmark bookmark = new Bookmark();
bookmark.setViewType(1);
arrayList.add(bookmark);*/
}
private ArrayList<Bookmark> getSampleData(){
//Get the sample data
ArrayList<Bookmark> customerList = arrayList;
//create an empty array to hold the list of sorted Customers
ArrayList<Bookmark> sortedCustomers = new ArrayList<Bookmark>();
//get the JSON array of the ordered of sorted customers
String jsonListOfSortedCustomerId = mSharedPreferences.getString(LIST_OF_SORTED_DATA_ID, "");
//check for null
assert jsonListOfSortedCustomerId != null;
if (!jsonListOfSortedCustomerId.isEmpty()){
//convert JSON array into a List<Long>
Gson gson = new Gson();
ArrayList<String> listOfSortedCustomersId = gson.fromJson(jsonListOfSortedCustomerId, new TypeToken<ArrayList<String>>(){}.getType());
//build sorted list
if (listOfSortedCustomersId != null && listOfSortedCustomersId.size() > 0){
for (String id: listOfSortedCustomersId){
for (Bookmark customer: customerList){
if (id.equals(customer.getId())){
sortedCustomers.add(customer);
customerList.remove(customer);
break;
}
}
}
}
//if there are still customers that were not in the sorted list
//maybe they were added after the last drag and drop
//add them to the sorted list
if (customerList.size() > 0){
sortedCustomers.addAll(customerList);
}
return sortedCustomers;
}else {
return customerList;
}
}
@Override
public void onResume() {
super.onResume();
buildBookmarkArrayListfromDB();
}
}
Adapter.class
public class AdapterForBookmark extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int ITEM_TYPE_ONE = 0;
public static final int ITEM_TYPE_TWO = 1;
ArrayList<Bookmark> arrayList;
String BASE_URL = "https://besticon-demo.herokuapp.com/icon?url=";
private Context context;
private int lastPosition = -1;
private Bookmark bookmark;
public AdapterForBookmark(Context context, ArrayList<Bookmark> arrayList, Bookmark bookmark) {
this.context = context;
this.arrayList = arrayList;
this.bookmark = bookmark;
}
public AdapterForBookmark(Context context, ArrayList<Bookmark> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = null;
if (viewType == ITEM_TYPE_ONE) {
view = LayoutInflater.from(context).inflate(R.layout.speed_link_item, parent, false);
return new ViewHolder(view);
} else if (viewType == ITEM_TYPE_TWO) {
view = LayoutInflater.from(context).inflate(R.layout.not_active_item, parent, false);
return new TextViewHolder(view);
} else {
return null;
}
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
final int itemType = getItemViewType(position);
final Bookmark bookmark = (Bookmark) this.arrayList.get(position);
if (itemType == ITEM_TYPE_ONE) {
final ViewHolder viewHolder = (ViewHolder) holder;
Animation animation = AnimationUtils.loadAnimation(context, (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top);
ViewHolder.tvName.startAnimation(animation);
viewHolder.tvMove.startAnimation(animation);
viewHolder.tvDel.startAnimation(animation);
viewHolder.tvIcon.startAnimation(animation);
ViewHolder.tvName.setText(arrayList.get(position).getName());
lastPosition = position;
String imageUrl = BASE_URL + arrayList.get(position).getSearchUrl() + "&size=32";
RequestOptions requestOptions = new RequestOptions();
int resID = context.getResources().getIdentifier(String.valueOf(arrayList.get(position).getIcon()), "drawable", context.getPackageName()); // if resID == 0 means the icon is not available in drawable folder
if (resID == 0) {
Glide.with(context)
.load(imageUrl)
.apply(requestOptions
.placeholder(R.drawable.default_favicon)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.fitCenter())
.into(viewHolder.tvIcon);
} else {
viewHolder.tvIcon.setImageResource(resID);
}
if (bookmark.getHidden() != null) {
viewHolder.tvDel.setImageResource(R.drawable.ic_move_add);
} else
viewHolder.tvDel.setImageResource(R.drawable.ic_move_del);
viewHolder.tvDel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
bookmark.setHidden("hidden");
arrayList.remove(position);
notifyDataSetChanged();
}
});
viewHolder.tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, ActivityChangeBookmark.class);
Bundle extras = new Bundle();
viewHolder.tvIcon.buildDrawingCache();
Bitmap image = viewHolder.tvIcon.getDrawingCache();
intent.putExtra("selectedNote", arrayList.get(position));
extras.putParcelable("Image", image);
intent.putExtras(extras);
v.getContext().startActivity(intent);
}
});
} else if (itemType == ITEM_TYPE_TWO) {
TextViewHolder textViewHolder = (TextViewHolder) holder;
textViewHolder.textView.setText("Inactive Bookmarks");
}
}
@Override
public int getItemViewType(int position) {
// based on you list you will return the ViewType
if (arrayList.get(position).getViewType() == 0) {
return ITEM_TYPE_ONE;
} else {
return ITEM_TYPE_TWO;
}
}
@Override
public int getItemCount() {
return arrayList.size();
}
@Override
public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewDetachedFromWindow(holder);
holder.itemView.clearAnimation();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private static TextView tvName, tvId, tvSearchUrl, tvNativeUrl;
ImageView tvIcon, tvMove, tvDel;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvSiteTitle);
tvIcon = itemView.findViewById(R.id.ivFav);
tvMove = itemView.findViewById(R.id.ivMove);
tvDel = itemView.findViewById(R.id.ivDel);
tvDel.setVisibility(View.VISIBLE);
tvMove.setVisibility(View.VISIBLE);
}
}
public class TextViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public TextViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.inactiveBookmark);
}
}
SQLite.DB
public class BookmarkDB extends SQLiteOpenHelper {
public static final String DBNAME = "bookmarks.db"; // The name of the database file
public static final int DBVERSION = 1; // The Database version
public static final String TBL_BOOKMARK = "bookmark";
public static final String COL_ID = BaseColumns._ID; // equates to _id
public static final String COl_NAME = "name";
public static final String COl_HIDDEN = "hidden";
public static final String COL_ICON = "icon";
public static final String COL_NATIVEURL = "nativeurl";
public static final String COL_SEARCHURL = "searchurl";
SQLiteDatabase mDB;
Context mContext;
public BookmarkDB(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
// The SQL to be used to create the table
String crt_bookmark_tbl_sql = "CREATE TABLE IF NOT EXISTS " + TBL_BOOKMARK + "(" +
COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COl_NAME + " TEXT, " +
COl_HIDDEN + " INTEGER, " +
COL_ICON + " TEXT, " +
COL_NATIVEURL + " TEXT," +
COL_SEARCHURL + " TEXT" +
")";
db.execSQL(crt_bookmark_tbl_sql); // CREATE THE TABLE
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF TABLE EXISTS " + DBNAME);
onCreate(db);
}
public void updateName(String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TBL_BOOKMARK + " SET " + COl_NAME +
" = '" + newName + "' WHERE " + COL_ID + " = '" + id + "'" +
" AND " + COl_NAME + " = '" + oldName + "'";
db.execSQL(query);
}
public long addBookmark(long id, String name, boolean hidden, String icon, String nativeurl, String searchurl) {
ContentValues cv = new ContentValues();
cv.put(COl_HIDDEN, hidden);
cv.put(COl_NAME, name);
cv.put(COL_ICON, icon);
cv.put(COL_NATIVEURL, nativeurl);
cv.put(COL_SEARCHURL, searchurl);
return mDB.insert(TBL_BOOKMARK, null, cv);
// uses the convenience insert method that builds the SQL
}
public ArrayList<Bookmark> getAllBookmarks() {
ArrayList<Bookmark> rv = new ArrayList<>();
Cursor csr = mDB.query(TBL_BOOKMARK, null, null, null, null, null, null);
while (csr.moveToNext()) {
Bookmark b = new Bookmark();
b.setId(csr.getString(csr.getColumnIndex(COL_ID)));
int Icon = csr.getInt(csr.getColumnIndex(COL_ICON));
String name = csr.getString(csr.getColumnIndex(COl_NAME));
String searchUrl = csr.getString(csr.getColumnIndex(COL_SEARCHURL));
b.setIcon(Icon);
b.setName(name);
b.setSearchUrl(searchUrl);
b.setViewType(csr.getInt(csr.getColumnIndex(COl_NAME)));
b.setNativeUrl(csr.getString(csr.getColumnIndex(COL_NATIVEURL)));
rv.add(b);
}
return rv;
}
public void deleteBookmark(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TBL_BOOKMARK + " WHERE "
+ COL_ID + " = '" + id + "'" +
" AND " + COl_NAME + " = '" + name + "'";
Log.d("Deleted", "Item" + query);
db.execSQL(query);
}
public boolean ifNativeUrlExists(String nativeUrl) {
boolean rv = false;
String whereclause = COL_NATIVEURL + "=?";
String[] whereargs = new String[]{nativeUrl};
Cursor csr = mDB.query(TBL_BOOKMARK, null, whereclause, whereargs, null, null, null);
if (csr.getCount() > 0) {
rv = true;
}
csr.close();
return rv;
}
public Cursor getItemID(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL_ID + " FROM " + TBL_BOOKMARK + " WHERE " +
COl_NAME + " ='" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
public void updateOrder(long rowID, int newPos) {
ContentValues cv = new ContentValues();
cv.put(COL_ID, newPos);
mDB.update(TBL_BOOKMARK, cv, COL_ID + "=" + rowID, null);
}
}
来源:https://stackoverflow.com/questions/54867970/collections-swap-changes-the-position-of-the-recyclerview-but-it-doesnt-show-an