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根本没必要提,因为这与手头的问题无关。