RecyclerView 在 JSON 中保存元素
RecyclerView save elements in JSON
我有 recyclerview(在片段中)和带有元素之一的详细信息的片段。一切都很好,但是当我的数据被保存时。我的 JSON 文件中有不好的结果。每次我打开列表元素时,他都会在 JSON 文件中添加新元素,而他必须覆盖自己。
我的Activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_page_activity);
Log.i("MainActivity", "onCreate");
if(savedInstanceState==null) {
getFragment(new ObjectListFragment());
}
}
public void getFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
if (mFragment == null) {
mFragment = fragment;
fm.beginTransaction()
.add(R.id.fragment_container, mFragment)
.commit();
}
if (mFragment != null) {
mFragment = fragment;
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}
我的模特:
public class Object {
private static final String JSON_ID = "id";
private static final String JSON_TITLE = "title";
private UUID mId;
private String mTitle;
public Object() {
mId=UUID.randomUUID();
}
public Object(JSONObject json) throws JSONException {
mId = UUID.fromString(json.getString(JSON_ID));
mTitle = json.getString(JSON_TITLE);
}
public JSONObject toJSON()throws JSONException{
JSONObject json = new JSONObject();
json.put(JSON_ID, mId.toString());
json.put(JSON_TITLE, mTitle);
return json;
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
@Override
public String toString() {
return mTitle;
}
}
对象实验室:
public class ObjectLab {
private static final String TAG = "ObjectLab";
private static final String FILENAME = "reminder.json";
private ObjectJSON mSerializer;
private ArrayList<Object> mObjects;
private static ObjectLab sObjectLab;
private Context mContext;
private ObjectLab(Context context){
mContext = context;
mSerializer = new ObjectJSON(mContext, FILENAME);
try {
mObjects = mSerializer.loadReminders();
} catch (Exception e) {
mObjects = new ArrayList<Object>();
Log.e(TAG, "Error loading crimes: ", e);
}
}
public static ObjectLab get(Context c){
if(sObjectLab == null){
sObjectLab = new ObjectLab(c.getApplicationContext());
}
return sObjectLab;
}
public ArrayList<Object> getObjects(){
return mObjects;
}
public Object getReminder(UUID id){
for(Object c : mObjects){
if(c.getId().equals(id))
return c;
}
return null;
}
public void addReminder(Object c){
mObjects.add(0,c);
}
public void deleteReminder(Object c){
mObjects.remove(c);
}
public boolean saveReminders(){
try{
mSerializer.saveReminders(mObjects);
Log.d(TAG, "reminders saved to file");
return true;
}catch (Exception e){
Log.e(TAG, "Error saving crimes: ", e);
return false;
}
}
对象JSON:
public class ObjectJSON {
private Context mContext;
private String mFilename;
public ObjectJSON(Context context, String filename) {
mContext = context;
mFilename = filename;
}
public void saveReminders(ArrayList<Object> objects) throws JSONException, IOException {
Log.i("Save","saveReminders");
JSONArray array = new JSONArray();
for (Object f : objects)
array.put(f.toJSON());
Writer writer = null;
try {
OutputStream out = mContext.openFileOutput(mFilename, Context.MODE_APPEND);
writer = new OutputStreamWriter(out);
writer.write(array.toString());
} finally {
if (writer != null)
writer.close();
}
}
public ArrayList<Object> loadReminders() throws IOException, JSONException {
Log.i("Save","loadReminders");
ArrayList<Object> objects = new ArrayList<Object>();
BufferedReader reader = null;
try {
InputStream in = mContext.openFileInput(mFilename);
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder jsonString = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
jsonString.append(line);
}
JSONArray array = (JSONArray) new JSONTokener(jsonString.toString())
.nextValue();
for (int i = 0; i < array.length(); i++) {
objects.add(new Object(array.getJSONObject(i)));
}
} catch (FileNotFoundException e) {
//when 0
} finally {
if (reader != null)
reader.close();
}
return objects;
}
ObjectListFragment:
public class ObjectListFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerAdapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.reminder_activity, container, false);
Log.i("ObjectListFragment", "onCreateView");
final ArrayList<Object> mData = ObjectLab.get(getActivity()).getObjects();
getActivity().setTitle("Object");
mRecyclerView = (RecyclerView)v. findViewById(R.id.my_recycler_view);
//registerForContextMenu(mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter(mData);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(v.getContext(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.i("ObjectListFragment", "onItemClick");
Object f = mData.get(position);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}));
return v;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_main, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
Log.d("Testing", "ID == " + id);
switch (id) {
case R.id.action_settings: {
Log.d("onOptionsItemSelected", " SETTings");
Object f = new Object();
ObjectLab.get(getActivity()).addReminder(f);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
return true;
}
}
return super.onOptionsItemSelected(item);
}
}
回收器适配器:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
ArrayList<Object> mData;
public RecyclerAdapter(ArrayList<Object> objects) {
mData = objects;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.reminder_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTitleTextView.setText(mData.get(position).getTitle());
}
@Override
public int getItemCount() {
return mData.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView mTitleTextView;
public ViewHolder(View itemView) {
super(itemView);
mTitleTextView = (TextView) itemView.findViewById(R.id.forget_list_titleTextView);
}
}
RecyclerItemClickListener:
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
return true;
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
和最后一个 ObjectFragmet
public class ObjectFragment extends Fragment{
public static final String EXTRA_REMINDER_ID = "id";
private Object mObject;
public static ObjectFragment newInstance(UUID crimeId) {
Log.i("ObjectFragment", "newInstance");
Bundle args = new Bundle();
args.putSerializable(EXTRA_REMINDER_ID, crimeId);
ObjectFragment fragment = new ObjectFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID uuid = (UUID) getArguments().getSerializable(EXTRA_REMINDER_ID);
Log.i("ObjectFragment", " "+uuid);
mObject = ObjectLab.get(getContext()).getReminder(uuid);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.remind_act, container, false);
EditText editText = (EditText)v.findViewById(R.id.editText1);
editText.setText(mObject.getTitle());
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mObject.setTitle(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
return v;
}
@Override
public void onPause() {
super.onPause();
Log.i("ObjectFragment", "onPause");
ObjectLab.get(getActivity()).saveReminders();
}
Links to the project(Android Studio).
我的问题是我没有。很高兴听到您对该主题以及该主题的所有评论和建议。
你的帮助不会无人值守。
打开 OutputStream
写入文件时,您使用了 Context.MODE_APPEND
标志,这导致写入操作按照您的意图追加而不是覆盖,将其更改为:
OutputStream out = mContext.openFileOutput(mFilename, 0);
另外,RecyclerView
根本没必要提,因为这与手头的问题无关。
我有 recyclerview(在片段中)和带有元素之一的详细信息的片段。一切都很好,但是当我的数据被保存时。我的 JSON 文件中有不好的结果。每次我打开列表元素时,他都会在 JSON 文件中添加新元素,而他必须覆盖自己。
我的Activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.start_page_activity);
Log.i("MainActivity", "onCreate");
if(savedInstanceState==null) {
getFragment(new ObjectListFragment());
}
}
public void getFragment(Fragment fragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
if (mFragment == null) {
mFragment = fragment;
fm.beginTransaction()
.add(R.id.fragment_container, mFragment)
.commit();
}
if (mFragment != null) {
mFragment = fragment;
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}
我的模特:
public class Object {
private static final String JSON_ID = "id";
private static final String JSON_TITLE = "title";
private UUID mId;
private String mTitle;
public Object() {
mId=UUID.randomUUID();
}
public Object(JSONObject json) throws JSONException {
mId = UUID.fromString(json.getString(JSON_ID));
mTitle = json.getString(JSON_TITLE);
}
public JSONObject toJSON()throws JSONException{
JSONObject json = new JSONObject();
json.put(JSON_ID, mId.toString());
json.put(JSON_TITLE, mTitle);
return json;
}
public UUID getId() {
return mId;
}
public String getTitle() {
return mTitle;
}
public void setTitle(String title) {
mTitle = title;
}
@Override
public String toString() {
return mTitle;
}
}
对象实验室:
public class ObjectLab {
private static final String TAG = "ObjectLab";
private static final String FILENAME = "reminder.json";
private ObjectJSON mSerializer;
private ArrayList<Object> mObjects;
private static ObjectLab sObjectLab;
private Context mContext;
private ObjectLab(Context context){
mContext = context;
mSerializer = new ObjectJSON(mContext, FILENAME);
try {
mObjects = mSerializer.loadReminders();
} catch (Exception e) {
mObjects = new ArrayList<Object>();
Log.e(TAG, "Error loading crimes: ", e);
}
}
public static ObjectLab get(Context c){
if(sObjectLab == null){
sObjectLab = new ObjectLab(c.getApplicationContext());
}
return sObjectLab;
}
public ArrayList<Object> getObjects(){
return mObjects;
}
public Object getReminder(UUID id){
for(Object c : mObjects){
if(c.getId().equals(id))
return c;
}
return null;
}
public void addReminder(Object c){
mObjects.add(0,c);
}
public void deleteReminder(Object c){
mObjects.remove(c);
}
public boolean saveReminders(){
try{
mSerializer.saveReminders(mObjects);
Log.d(TAG, "reminders saved to file");
return true;
}catch (Exception e){
Log.e(TAG, "Error saving crimes: ", e);
return false;
}
}
对象JSON:
public class ObjectJSON {
private Context mContext;
private String mFilename;
public ObjectJSON(Context context, String filename) {
mContext = context;
mFilename = filename;
}
public void saveReminders(ArrayList<Object> objects) throws JSONException, IOException {
Log.i("Save","saveReminders");
JSONArray array = new JSONArray();
for (Object f : objects)
array.put(f.toJSON());
Writer writer = null;
try {
OutputStream out = mContext.openFileOutput(mFilename, Context.MODE_APPEND);
writer = new OutputStreamWriter(out);
writer.write(array.toString());
} finally {
if (writer != null)
writer.close();
}
}
public ArrayList<Object> loadReminders() throws IOException, JSONException {
Log.i("Save","loadReminders");
ArrayList<Object> objects = new ArrayList<Object>();
BufferedReader reader = null;
try {
InputStream in = mContext.openFileInput(mFilename);
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder jsonString = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
jsonString.append(line);
}
JSONArray array = (JSONArray) new JSONTokener(jsonString.toString())
.nextValue();
for (int i = 0; i < array.length(); i++) {
objects.add(new Object(array.getJSONObject(i)));
}
} catch (FileNotFoundException e) {
//when 0
} finally {
if (reader != null)
reader.close();
}
return objects;
}
ObjectListFragment:
public class ObjectListFragment extends Fragment {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerAdapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.reminder_activity, container, false);
Log.i("ObjectListFragment", "onCreateView");
final ArrayList<Object> mData = ObjectLab.get(getActivity()).getObjects();
getActivity().setTitle("Object");
mRecyclerView = (RecyclerView)v. findViewById(R.id.my_recycler_view);
//registerForContextMenu(mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new RecyclerAdapter(mData);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(v.getContext(), new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.i("ObjectListFragment", "onItemClick");
Object f = mData.get(position);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
}
}));
return v;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_main, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
Log.d("Testing", "ID == " + id);
switch (id) {
case R.id.action_settings: {
Log.d("onOptionsItemSelected", " SETTings");
Object f = new Object();
ObjectLab.get(getActivity()).addReminder(f);
FragmentManager fm = getFragmentManager();
Fragment mFragment = fm.findFragmentById(R.id.fragment_container);
Bundle bundle = new Bundle();
bundle.putSerializable(ObjectFragment.EXTRA_REMINDER_ID, f.getId());
if (mFragment != null) {
mFragment = new ObjectFragment();
mFragment.setArguments(bundle);
fm.beginTransaction().addToBackStack(null)
.replace(R.id.fragment_container, mFragment)
.commit();
}
return true;
}
}
return super.onOptionsItemSelected(item);
}
}
回收器适配器:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
ArrayList<Object> mData;
public RecyclerAdapter(ArrayList<Object> objects) {
mData = objects;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.reminder_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTitleTextView.setText(mData.get(position).getTitle());
}
@Override
public int getItemCount() {
return mData.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView mTitleTextView;
public ViewHolder(View itemView) {
super(itemView);
mTitleTextView = (TextView) itemView.findViewById(R.id.forget_list_titleTextView);
}
}
RecyclerItemClickListener:
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
return true;
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
和最后一个 ObjectFragmet
public class ObjectFragment extends Fragment{
public static final String EXTRA_REMINDER_ID = "id";
private Object mObject;
public static ObjectFragment newInstance(UUID crimeId) {
Log.i("ObjectFragment", "newInstance");
Bundle args = new Bundle();
args.putSerializable(EXTRA_REMINDER_ID, crimeId);
ObjectFragment fragment = new ObjectFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UUID uuid = (UUID) getArguments().getSerializable(EXTRA_REMINDER_ID);
Log.i("ObjectFragment", " "+uuid);
mObject = ObjectLab.get(getContext()).getReminder(uuid);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.remind_act, container, false);
EditText editText = (EditText)v.findViewById(R.id.editText1);
editText.setText(mObject.getTitle());
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
mObject.setTitle(charSequence.toString());
}
@Override
public void afterTextChanged(Editable editable) {
}
});
return v;
}
@Override
public void onPause() {
super.onPause();
Log.i("ObjectFragment", "onPause");
ObjectLab.get(getActivity()).saveReminders();
}
Links to the project(Android Studio). 我的问题是我没有。很高兴听到您对该主题以及该主题的所有评论和建议。 你的帮助不会无人值守。
打开 OutputStream
写入文件时,您使用了 Context.MODE_APPEND
标志,这导致写入操作按照您的意图追加而不是覆盖,将其更改为:
OutputStream out = mContext.openFileOutput(mFilename, 0);
另外,RecyclerView
根本没必要提,因为这与手头的问题无关。