0

Я хочу запрограммировать простой органайзер с Notes. У меня есть база данных SQLite с некоторыми данными, как показано ниже:Хороший способ создания динамического списка с данными из SQLite?

_id | time | date | text 
1 | 9:45 | 12.01| blabla 
2 | 21:01| 13.01| albalb 
...| ... | ... | ... 

Также у меня есть класс Note:

public class Note { 
    private int id; 
    private String time; 
    private String date; 
    private String text; 
    public Note(final int id, final String time, final String date, final String text){ 
     setId(id); 
     setTime(time); 
     setDate(date); 
     setText(text); 
    } 
    public int getId(){ 
     return id; 
    } 
    public String getTime(){ 
     return time; 
    } 
    public String getDate(){ 
     return date; 
    } 
    public String getText(){ 
     return text; 
    } 

    void setId(final int id){ 
     this.id = id; 
    } 
    void setTime(final String time){ 
     this.time = time; 
    } 
    void setDate(final String date){ 
     this.date = date; 
    } 
    void setText(final String text){ 
     this.text = text; 
    } 
} 

И NotesManager:

public class NotesManager { 
    private static final String TABLE_NAME = "NotesListTable"; 
    private static final String KEY_TIME = "time"; 
    private static final String KEY_DATE = "date"; 
    private static final String KEY_TEXT = "text"; 
    private static final String KEY_ID = "_id"; 

    private final SQLiteDatabase db; 
    public NotesManager(SQLiteDatabase db){ 
     this.db = db; 
    } 
    public void save(final ContentValues cv){ 
     db.insert(TABLE_NAME, null, cv); 
    } 
    public void delete(final int id){ 
     db.delete(TABLE_NAME, KEY_ID + "=" + id, null); 
    } 
    public Note getNoteById(final int id){ 
     Cursor mCursor = db.query(TABLE_NAME, null, KEY_ID + "=" + id, null, null, null, null, null); 
     if (mCursor != null) { 
      mCursor.moveToFirst(); 
     } 
     return new Note(mCursor.getInt(mCursor.getColumnIndex(KEY_ID)), 
       mCursor.getString(mCursor.getColumnIndex(KEY_TIME)), 
       mCursor.getString(mCursor.getColumnIndex(KEY_DATE)), 
       mCursor.getString(mCursor.getColumnIndex(KEY_TEXT))); 
    } 
    public Cursor getAllDataFromDB(){ 
     return db.query(TABLE_NAME, null, null, null, null, null, null); 
    } 
    public String[] getKeysArray(){ 
     return new String[] {KEY_ID, KEY_TIME, KEY_DATE, KEY_TEXT}; 
    } 
} 

У меня есть фрагмент с ListView : Он был создан Android Studio, на гайке я внес некоторые изменения, добавлен SimpleCursorAdapter

public class NotesListFragment extends Fragment implements AbsListView.OnItemClickListener { 

    private static final String ARG_SECTION_NUMBER = "section_number"; 
    private int mSectionNumber = 0; 
    private OnFragmentInteractionListener mListener; 
    private AbsListView mListView; 
    private SimpleCursorAdapter scAdapter; 
    private Cursor cursor; 
    ImageButton deleteButton; 
    NotesManager notesManager = new NotesManager(OrganizerApp.db); 

    public static NoesListFragment newInstance(int param1) { 
     NoesListFragment fragment = new NotesListFragment(); 
     Bundle args = new Bundle(); 
     args.putInt(ARG_SECTION_NUMBER, param1); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    public NotesListFragment() { 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (getArguments() != null) { 
      mSectionNumber = getArguments().getInt(ARG_SECTION_NUMBER); 
     } 
     cursor = NotesManager.getAllDataFromDB(); 
     //TODO: startManagingCursor(cursor) 

     //mAdapter = new ArrayAdapter<NotesListContent.NotesItem>(getActivity(), 
     //  android.R.layout.simple_list_item_1, android.R.id.text1, NotesListContent.ITEMS); 
     scAdapter = new SimpleCursorAdapter(getActivity(), 
       R.layout.note_list_rowlayout, 
       cursor, 
       notesManager.getKeysArray(), 
       new int[]{R.id.note_list_rowlayout_item1, 
         R.id.note_list_rowlayout_item2, 
         R.id.note_list_rowlayout_item3, 
         R.id.note_list_rowlayout_item4 }); 
     deleteButton = (ImageButton) getView(). 
       findViewById(R.id.note_list_rowlayout_deleteButton); 
     deleteButton.setOnClickListener(onClickDeleteButton); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_note, container, false); 

     // Set the adapter 
     mListView = (AbsListView) view.findViewById(android.R.id.list); 
     mListView.setAdapter(scAdapter); 
     //((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter); 

     // Set OnItemClickListener so we can be notified on item clicks 
     mListView.setOnItemClickListener(this); 

     return view; 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      mSectionNumber = getArguments().getInt(ARG_SECTION_NUMBER); 
      mListener = (OnFragmentInteractionListener) activity; 
      ((MainActivity) activity).onSectionAttached(mSectionNumber); 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() 
        + " must implement OnFragmentInteractionListener"); 
     } 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mListener = null; 
    } 


    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     if (null != mListener) { 
      // Notify the active callbacks interface (the activity, if the 
      // fragment is attached to one) that an item has been selected. 
      // mListener.onFragmentInteraction(NotesListContent.ITEMS.get(position).id); 
     } 
    } 

    public void setEmptyText(CharSequence emptyText) { // If list is empty. 
     View emptyView = mListView.getEmptyView(); 

     if (emptyView instanceof TextView) { 
      ((TextView) emptyView).setText(emptyText); 
     } 
    } 

    public interface OnFragmentInteractionListener { 
     // TODO: Update argument type and name 
     public void onFragmentInteraction(String id); 
    } 

    View.OnClickListener onClickDeleteButton = new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

     } 
    }; 

} 

Android студия также генерироваться NotesListContent.java:

public class NotesListContent { 

    public static List<Note> ITEMS = new ArrayList<Note>(); 

    //public static Map<String, Note> ITEM_MAP = new HashMap<String, Note>(); 

    private static void addItem(Note item) { 
     ITEMS.add(item); 
     //ITEM_MAP.put(item.id, item); 
    } 



    /** 
    * A dummy item representing a piece of content. 

    public static class NoteItem { 
     public String id; 
     public String content; 

     public NoteItem(String id, String content) { 
      this.id = id; 
      this.content = content; 
     } 

     @Override 
     public String toString() { 
      return content; 
     } 
    }*/ 
} 

Так что мое решение работает, но я думаю, что это плохо.

  1. Для чего мне нужен NotesListContent.java? Как я могу использовать его?
  2. Как я могу использовать ListView без устаревшего simpleCursorAdapter?
  3. Как удалить и добавить элементы без обновления все ListView?
  4. Особенно этот код кажется очень неудобным:

    scAdapter = новый SimpleCursorAdapter (getActivity(), R.layout.note_list_rowlayout, курсор, notesManager.getKeysArray(), новый INT [] {R .id.note_list_rowlayout_item1, R.id.note_list_rowlayout_item2, R.id.note_list_rowlayout_item3, R.id.note_list_rowlayout_item4});

+0

неудобно? Что неудобно в этом конструкторе? – pskink

ответ

1

Я сделал собственный менеджер заметок, поэтому постараюсь ответить на ваши вопросы.

Для чего мне нужен NotesListContent.java? Как я могу использовать его?

Это несколько MVC образец, разделение данных из вида. Постарайтесь думать об этом как о сущности или лучше, как о описании записи одной заметки.

Как использовать ListView без устаревшего simpleCursorAdapter?

a) с каких это simpleCursorAdapter обесценивается? Только один из его конструкторов.
б) Вы можете использовать второй конструктор, или расширить некоторый класс адаптера (например, ArrayAdapter) сам

Как удалять и добавлять элементы без обновления всех ListView?

Вы добавляете данные в свои данныеAdapter, затем устанавливаете dataAdapter в качестве адаптера для ListView (listview.setAdapter (адаптер)).
Если вы не вызываете access.notifyDataSetChanged() listview, представление не будет обновляться.

Особенно этот код кажется очень неудобным (...)

Что так неправильно об этом? Но если это так, не стесняйтесь использовать sth следующим образом:

String[] columns = new String[] { // The desired columns to be bound 
     "timestamp", 
     "title", 
     "content", 
}; 

// the XML defined views which the data will be bound to 
int[] map_to = new int[] { 
     R.id.timestamp, 
     R.id.title, 
     R.id.content, 
}; 

dataAdapter = new SimpleCursorAdapter(
     this, R.layout.some_xml_here, 
     db.getAllItems(), 
     columns, 
     map_to, 
     0); 
+0

Спасибо за ответ! Может быть, мне не следует использовать способ «База данных -> временный курсор -> ListView» и должен делать что-то вроде «База данных -> временный курсор -> Список заметок (список в NotesListContent.java) -> ListView"? Потому что у меня будет список заметок, с которыми легко работать. Если это лучше, чем я могу создать Список ? И как я могу изменить ArrayAdapter, чтобы поместить несколько строк в каждую строку? Android рекомендует использовать CursorAdapet, как я помню. – Porfiriy

+0

Ну, это зависит от того, насколько плотно написано все ваше приложение, но в целом да, это нужно использовать ArrayList . Чтобы создать ArrayList Вам нужно будет создать CustomCursorAdapter и расширить базовый адаптер, предполагая, что вы хотите, чтобы он был заполнен с DB так же, как simpleCursorAdapter, иначе просто List list = new ArrayList (). Вы можете найти несколько примеров того, как это сделать, обеспечить реализацию getView() достаточно, оно короткое, но может быть скорректировано с учетом ваших потребностей – brainovergrow