7

ВведениеEditText Сохранить данные/обновления фрагмента в FragmentStatePagerAdapter

У меня есть деятельность, с книгой, которая содержит ArrayList типа «страницы» и обрабатывать все страницы, которые я решил использовать FragmentStatePagerAdapter, в котором один моего фрагмента содержит одну страницу.

Я создал интерфейс для связи между каждым фрагментом в пейджере и деятельностью отца. Метод, который мне нужен в этом интерфейсе, - это обновление страницы, показанной в фрагменте, поэтому я сделал реализацию активности отца, интерфейс для получения данных из фрагмента и сохранил их на странице, чтобы сохранить в arraylist.

Каждый фрагмент имеет EditText, в котором пользователь может писать, и я устанавливаю addTextChangedListener, чтобы поймать момент, когда пользователь перестает писать. Когда пользователь перестает писать в EditText, в onTextChanged() я вызываю функцию, реализованную в отчёте активности.

Это мой код действия

public class BookEditorActivity implements BookEditorFragment.EditorFrToEditorActInterface { 

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

     Bundle extras = getIntent().getExtras(); 
     b = (Book) extras.get("book"); 

     setBookViewPager(b); 

    } 

    private void setBookViewPager(Book b) { 
     mBookViewPager = (ViewPager) findViewById(R.id.book_editor_pager); 
     mBookViewPagerAdapter = new BookViewPagerAdapter(getSupportFragmentManager(), b); 
     mBookViewPager.setAdapter(mBookViewPagerAdapter); 
    } 

    @Override 
    public void saveBookPageTextContent(String textContent) { 

     int current = mBookViewPager.getCurrentItem(); 

     if (b.getPages().get(current) instanceof BookPageText) { 
      ((BookPageText) b.getPages().get(current)).setContentPageText(textContent); 
     } 
    } 

    @Override 
    public void newBookPageText() { 
     int current = mBookViewPager.getCurrentItem(); 

     BookPageText bookPageText = new BookPageText(); 
     bookPageText.setContentPageText(""); 

     b.getPages().add(b.getPages().size() - 1, bookPageText); 

     setIndicator(current + 1, b.getPages().size()); 
     mBookViewPagerAdapter.notifyDataSetChanged(); 

    } 
} 

Это фрагмент кода

public class BookEditorFragment extends Fragment { 

    private EditorFrToEditorActInterface mCallback; 

    public interface EditorFrToEditorActInterface { 
     void newBookPageText(); 
     void saveBookPageTextContent(String s); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     Bundle pageContent = getArguments(); 
     if (pageContent != null) { 
      page = pageContent.getParcelable("page"); 
     } 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     if (page instanceof BookPageText) { 
      BookPageText bookPage = (BookPageText) page; 

      mView = inflater.inflate(R.layout.book_page_text_fragment, container, false); 
      contentPage = (EditText) mView.findViewById(R.id.content_text); 

      String contentPageText = bookPage.getContentPageText(); 
      contentPage.setText(contentPageText.isEmpty() ? "" : Html.fromHtml(contentPageText)); 

      contentPage.addTextChangedListener(new TextWatcher() { 
       public void onTextChanged(CharSequence c, int start, int before, int count) { 
        mCallback.saveBookPageTextContent(c.toString()); 
       } 

       public void beforeTextChanged(CharSequence c, int start, int count, int after) { 
       } 

       public void afterTextChanged(Editable c) { 
       } 
      }); 

     } 

     return mView; 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     try { 
      mCallback = (EditorFrToEditorActInterface) context; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(context.toString() 
        + " must implement NewPageInterface"); 
     } 
    } 

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

    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
      case R.id.editor_new_text: 
       mCallback.newBookPageText(); 
      break; 
     } 
    } 

} 

Это код FragmentStatePagerAdapter

public class BookViewPagerAdapter extends FragmentStatePagerAdapter { 
    private ArrayList<Object> bookPages = new ArrayList<>(); 
    private final SparseArray<WeakReference<BookEditorFragment>> instantiatedFragments = new SparseArray<>(); 

    public BookViewPagerAdapter(FragmentManager fm, Book b) { 
     super(fm); 
     this.bookPages = b.getPages(); 
    } 

    @Override 
    public Fragment getItem(int position) { 

     Object page = bookPages.get(position); 

     Bundle pageContent = new Bundle(); 
     if (page instanceof BookPageText) { 
      BookPageText bookPageText = (BookPageText) page; 
      pageContent.putParcelable("page", bookPageText); 
     } 

     BookEditorFragment fragment = new BookEditorFragment(); 
     fragment.setArguments(pageContent); 
     return fragment; 
    } 

    @Override 
    public int getCount() { 
     return bookPages.size(); 
    } 

    @Override 
    public Object instantiateItem(final ViewGroup container, final int position) { 
     final BookEditorFragment fragment = (BookEditorFragment) super.instantiateItem(container, position); 
     instantiatedFragments.put(position, new WeakReference<>(fragment)); 
     return fragment; 
    } 

    @Override 
    public void destroyItem(final ViewGroup container, final int position, final Object object) { 
     instantiatedFragments.remove(position); 
     super.destroyItem(container, position, object); 
    } 

    @Nullable 
    public Fragment getFragment(final int position) { 
     final WeakReference<BookEditorFragment> wr = instantiatedFragments.get(position); 
     if (wr != null) { 
      return wr.get(); 
     } else { 
      return null; 
     } 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     int position = bookPages.indexOf(object); 
     return position == -1 ? POSITION_NONE : position; 
    } 
} 

Благодаря длине кода я удалены некоторые детали, как onClickListener, onPageSelectionListener и другие типы страниц, которые я создаю правильно Теперь.

Проблема

Эта логика, кажется, работает правильно, но каждый раз, когда я изменить содержание в EditText во фрагменте, близкий фрагмент слева также обновляется, и я не знаю, Зачем.

enter image description here
Как вы можете видеть на картинке, если я пишу что-то в EditText2, то же содержание будет появляться в EditText1, и это не имеет никакого смысла.

Другая проблема заключается в том, что когда я добавляю новую страницу в книгу, страница создается правильно, но с содержанием предыдущей страницы, и это не имеет смысла. (Опять же!)

Мои попытки

1) Я попытался поймать onFocusChange вместо использования addTextChangedListener, но ничего не изменилось.

2) Я попытался реализовать другую логику, используя onChangePageListener(), но в этом случае я потерял mBookViewPager.getCurrentItem(), поэтому обновление идет не так.

3) Я пробовал все эти должности: one, two, three и four.

Как я могу исправить это странное поведение? Возможно ли, что проблема в том, как я ссылаюсь на страницы в ArrayList книги?

Благодаря

+0

Можете ли вы предоставить ссылку на ваш код. Его трудно реплицировать с помощью кода, предоставленного вами. –

ответ

0

Некоторые из возможных ошибок я нашел в вашем implemantation есть.

  1. для управления текущей страницы posetion реализации

    mViewPager.setOnPageChangeListener(new OnPageChangeListener() { 
          @Override 
          public void onPageSelected(int p) { 
          current = p; 
          Log.e("Postion", "" + p); 
          } 
    
          @Override 
          public void onPageScrolled(int arg0, float arg1, int arg2) {} 
    
          @Override 
          public void onPageScrollStateChanged(int arg0) {} 
         }); 
    
  2. ViewPager автоматически загружать privious и следующий вид для privent он установлен пейджера OffscreenPageLimit по телефону Mathod

    mViewPager.setOffscreenPageLimit(); 
    
  3. всегда убедитесь, что если вы используете оператор if в адаптере, вы должны всегда ставить его счетчик a else заявление даже для любого значения по умолчанию.

    if (page instanceof BookPageText) { 
        BookPageText bookPageText = (BookPageText) page; 
        pageContent.putParcelable("page", bookPageText); 
    } 
    
+0

Я внес изменения, которые вы предложили, но ничего не изменилось ... Возможно ли, что проблема находится в объекте модели? Я думал об этом, потому что для сохранения моей книги я создал класс, который реализует «Serializable», и внутри класса у меня есть ссылка на другой класс, который реализует «Serializable» и «Parcelable». Каждый раз, когда я извлекаю и сохраняю книгу, она находится в/из файла. – michoprogrammer

+0

Да, это может быть так, вы можете передавать данные через EventBus вместо Serializable или Parcelable. , если вы хотите сохранить эти данные, затем используйте Gson для преобразования вашей модели в строку и сохраните эту строку в предпочтении, вы можете получить эту строку и преобразовать ее в объект модели с помощью Gson. – RBK

+0

Я начал вчера в новом филиале преобразование в json-версию, и я надеюсь, что это будет правильный выбор. Я не понимаю, где я могу использовать EventBus или почему использовать EventBus вместо простого пакета. – michoprogrammer

Смежные вопросы