7

Wiem, że są tu już pewne tematy, ale nie mogłem znaleźć rozwiązania, które mógłbym zastosować w mojej sprawie.Jak usunąć fragment z FragmentPagerAdapter?

Mam działającą przesuwaną galerię, używając niestandardowych FragmentActivity i FragmentPagerAdapter, która zawiera listę Fragmentów.

Wewnątrz FragmentActivity jest "usuń" ImageView. Po kliknięciu wywoływana jest funkcja deleteMedia(), która następnie powinna usunąć bieżącą wartość Fragment, a następnie wyświetlić następujące Fragment. Jak miałbym to zrobić w moim przykładzie?

FragmentActivity:

public class GalleryPagerActivity extends FragmentActivity implements OnClickListener { 

    private Intent intent; 
    private SharedPreferences settings; 
    private PagerAdapter mPagerAdapter; 
    private ViewPager mPager; 
    private List<Fragment> fragments; 
    private List<WhiteboardMedia> wiList; 

    private int selectedPosition; 
    private LinearLayout llTop; 
    private TextView tvTop; 
    private ImageView delete; 
    private ImageView share; 
    private TextView tvCounter; 
    private TextView tvFilename; 
    private TextView tvFilesize; 
    private TextView tvDate; 

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

     try { 
      super.setContentView(R.layout.gallery_pager); 

      intent = getIntent(); 

      Type collectionType = new TypeToken<List<WhiteboardMedia>>(){}.getType(); 

      wiList = gson.fromJson(intent.getStringExtra("wiList"), collectionType); 
      selectedPosition = intent.getIntExtra("position", 1); 

      llTop = (LinearLayout) findViewById(R.id.llTop); 
      llTop.setOnClickListener(this); 
      tvTop = (TextView) findViewById(R.id.tvTop); 
      tvTop.setOnClickListener(this); 
      delete = (ImageView) findViewById(R.id.imgDelete); 
      delete.setOnClickListener(this); 
      share = (ImageView) findViewById(R.id.imgShare); 
      share.setOnClickListener(this); 

      tvCounter = (TextView) findViewById(R.id.tvCounter); 
      tvFilename = (TextView) findViewById(R.id.tvFilename); 
      tvFilesize = (TextView) findViewById(R.id.tvFilesize); 
      tvDate = (TextView) findViewById(R.id.tvDate); 

      createContextMenu(); 
      initDropbox(); 
     } catch (Exception e) { 
      Log.e("GalleryPagerActivity", e.getLocalizedMessage()); 
     } 
    } 

    /** 
    * Initialise the pager 
    */ 
    private void initialisePager() { 
     mPager = (ViewPager) super.findViewById(R.id.viewpager); 
     mPager.setAdapter(this.mPagerAdapter); 
     mPager.setOnPageChangeListener(new GalleryPageListener(tvCounter, tvFilename, tvFilesize, tvDate, wiList)); 

     mPager.setCurrentItem(selectedPosition, true); 
     updatePage(selectedPosition); 
    } 

    public void updatePage(int position) 
    { 
     int focusedPage = position + 1; 
     Log.i("onPageSelected", "page selected " + position); 

     WhiteboardMedia wiImage = wiList.get(position); 

     String imageDate = "N/A"; 
     try { 
      Date dateTaken= new Date(); //wiImage.getDate(); 
      SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd"); 
      imageDate = sdf.format(dateTaken); 
     } catch (Exception e) { 
     } 

     try { 
      tvCounter.setText(focusedPage + "/" + wiList.size()); 
      tvFilename.setText(wiImage.getFilename()); 
      tvFilesize.setText(wiImage.getSize() + "a"); 
      tvDate.setText(imageDate); 
     } catch (Exception e) { 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
    } 

    private WhiteboardMedia getActiveWhiteboardImage() { 
     return wiList.get(mPager.getCurrentItem()); 
    } 

    private final int DELETE = 1; 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     menu.add(1, DELETE, 2, R.string.delete).setIcon(R.drawable.menu_btn_trash); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case DELETE: 
      deleteMedia(); 
      return true; 
     } 
     return super.onContextItemSelected(item); 
    } 

    @Override 
    public void onClick(View v) { 
     if (v == delete) { 
      deleteMedia(); 
     } 
    } 

    private void deleteMedia() { 
     // TODO delete the active Fragment and display the next Fragment in the list 
    } 

    /****************************************************************************** 
    * Context Menu 
    *****************************************************************************/ 
    private void createContextMenu() { 
     // context menu stuff 
    } 

    @Override 
    protected Dialog onCreateDialog(int id) { 
     // stuff 
    } 

} 

FragmentPagerAdapter:

public class GalleryPagerAdapter extends FragmentPagerAdapter { 

private final List<Fragment> fragments; 

public GalleryPagerAdapter(FragmentManager fm, List<Fragment> fragments) { 
    super(fm); 
    this.fragments = fragments; 
} 

@Override 
public Fragment getItem(int position) { 
    return this.fragments.get(position); 
} 

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

Dzięki za pomoc!

Odpowiedz

11

Po pierwsze, sugeruję, aby rozważyć zmianę swojego FragmentPagerAdapter, aby wyglądać bardziej jak the sample. Zwykle nie przechowujesz listy fragmentów, tak samo jak ArrayAdapter zwykle zawiera listę Views dla wierszy. Zwykle tworzysz fragmenty na żądanie, a ktoś inny trzyma listę.

Następnie, aby usunąć coś, usuń go z danych modelu (co zwykle zawija FragmentPagerAdapter). Upewnij się, że getCount() zwróci odpowiednią liczbę elementów. Następnie zadzwoń pod numer notifyDataSetChanged() na FragmentPagerAdapter, który powinien wywołać przerysowanie ViewPager.

+0

OK dziękuję do tej pory! Próbuję dostać mój kod jak w przykładzie. W moim kodzie przechodzę przez listę obiektów i wypełniam listę fragmentów odpowiednimi Fragmentami (Obraz, Dźwięk, Wideo). 'z (int i = 0; i

+1

@ user753827: 'getItem()' musiałby mieć smarte, aby zwrócić właściwy fragment. – CommonsWare

+2

Ugh, od dawna mam ten sam problem. Fragmenty nie zostają zebrane i pozostają tam wizualnie (w ich starej i złej pozycji), dopóki nie przewiniesz zbyt daleko w prawo/lewo, a system wykaże je i zsynchronizuje się. Masz pojęcie, co robię źle? Mój kod wygląda jak przykład. –

15

że to rozwiązanie używam:

mViewPager: jest widok używasz aby cię Fragment

mViewPager = (YourViewPager) findViewById(R.id.myPager); 

TABELA: jest tylko lista Integer położenia wszystkich moich Fragments

public void destroyAllItem() { 
     int mPosition = mViewPager.getCurrentItem(); 
     int mPositionMax = mViewPager.getCurrentItem()+1; 
     if (TABLE.size() > 0 && mPosition < TABLE.size()) { 
      if (mPosition > 0) { 
       mPosition--; 
      } 

      for (int i = mPosition; i < mPositionMax; i++) { 
       try { 
        Object objectobject = this.instantiateItem(mViewPager, TABLE.get(i).intValue()); 
        if (objectobject != null) 
         destroyItem(mViewPager, TABLE.get(i).intValue(), objectobject); 
       } catch (Exception e) { 
        Log.i(TAG, "no more Fragment in FragmentPagerAdapter"); 
       } 
      } 
     } 
    } 

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

     if (position <= getCount()) { 
      FragmentManager manager = ((Fragment) object).getFragmentManager(); 
      FragmentTransaction trans = manager.beginTransaction(); 
      trans.remove((Fragment) object); 
      trans.commit(); 
     } 
    } 
+0

To działa dla mnie, dzięki! –

+0

Perfect Douarbou! Dzięki ! – anthony

+0

Działa jak urok! Uratowany mój czas! Dziękuję Ci :) –

1

mogę znaleźć rozwiązanie ovverriding metodę "onPostResume()" działalności i wywołanie notifyDataSetChanged wewnątrz tego.

@Override 
protected void onPostResume() { 
    super.onPostResume(); 
    if(this.mCustomPagerAdapter!=null){ 
     this.mCustomPagerAdapter.notifyDataSetChanged(); 
    } 
}