私はこれについてすでにいくつかのトピックがあることを知っていますが、私の場合にうまくいくことができる解決策を見つけることができませんでした。
フラグメントのリストを保持するカスタムのFragmentActivity
とFragmentPagerAdapter
を使用したスライドギャラリーがあります。
FragmentActivity
内にはImageView
「削除」があります。クリックすると、関数deleteMedia()
が呼び出され、現在のFragment
が削除され、次のFragment
が表示されます。私の例では、どのようにそれを行う必要がありますか?
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();
}
}
手伝ってくれてありがとう!
まず、FragmentPagerAdapter
を サンプル のように変更することを検討することをお勧めします。通常、フラグメントのリストは保持しません。通常、行のArrayAdapter
のリストを保持するのはViews
だけです。通常、フラグメントはオンデマンドで作成し、他の誰かがリストを保持します。
次に、何かを削除するには、モデルデータからそれを削除します(FragmentPagerAdapter
が通常ラップするもの)。 getCount()
が正しい数のアイテムを返すことを確認してください。次に、FragmentPagerAdapter
でnotifyDataSetChanged()
を呼び出します。これにより、ViewPager
の再描画がトリガーされます。
それが私が使用しているソリューションです:
mViewPager:フラグメントを設定するために使用しているビューです
mViewPager = (YourViewPager) findViewById(R.id.myPager);
表:すべてのフラグメントの位置の単なる整数リストです
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();
}
}
アクティビティのメソッド「onPostResume()」を削除し、その中でnotifyDataSetChangedを呼び出すソリューションを見つけました。
@Override
protected void onPostResume() {
super.onPostResume();
if(this.mCustomPagerAdapter!=null){
this.mCustomPagerAdapter.notifyDataSetChanged();
}
}
FragmentPagerAdapterを使用して、ランダムな位置(常に最後ではない)でフラグメントを動的に追加および削除している場合は、getItemIdというより注意が必要なメソッドがあります。デフォルトでは、FragmentPagerAdapterはフラグメントのタグ名としてposition Combined viewIdを使用しますが、フラグメントを追加または削除すると位置が変わります。その結果、追加する位置が既存のフラグメントによって占められているため、空のページが表示される場合があります。この問題を解決するには、getItemIdをオーバーライドします。
@Override
public long getItemId(int position) {
long itemId = ...; //Provide your unique ID here according to you logic
return itemId;
}
私の場合、アダプターから1つのアイテムを削除しようとすると、次のようになります。
// get the position of item to remove
int position = getBinding().vp.getCurrentItem();
// remove the item from adapter
adapter.removeItem(position);
adapter.notifyDataSetChanged();
// minus one from the count
totalInvoice--;
updateTitle(getBinding().vp.getCurrentItem());
if (totalInvoice == 0) {
finish();
}
// set the adapter to view pager again
getBinding().vp.setAdapter(adapter);
// smooth scroll to given position
getBinding().vp.setCurrentItem(position);
上記で行った理由は、データリストから1つを削除したにもかかわらず、フラグメントのビューがまだ存在していることがわかったためです。したがって、ビューページャーに特定の位置のビューをインスタンス化させる必要があります。上記の答えは、すべてのフラグメントを削除しようとしてもうまくいきません。だから、私は再びページャーを表示するようにアダプターを設定する悪い方法を見つけました。