50

左/右スワイプでビューを切り替えるためにViewPagerを使用します。

ViewPagerにはアダプターが必要なので、これを作成しました。

public class ListViewPagerAdapter extends PagerAdapter {

protected static final String TAG = "ListViewPagerAdapter";
protected static final int NUM_VIEWS = 3;

protected final Activity mActivity;

public ListViewPagerAdapter(Activity activity) {
    mActivity = activity;
}

@Override
public int getCount() {
    return NUM_VIEWS;
}

@Override
public void startUpdate(View container) {}

@Override
public Object instantiateItem(View container, int position) {
    // ViewPager
    ViewPager viewPager = (ViewPager) container;

    // Wird verwendet, um die Views aufzurufen
    LayoutInflater layoutInflater = mActivity.getLayoutInflater();

    // Standardmäßig ist news eingeblendet
    View view = layoutInflater.inflate(R.layout.news_fragment, null);
    // Falls sich die Position verändert, so verändert sich auch die View
    if (position == 0) {
        view = layoutInflater.inflate(R.layout.favorite_fragment, null);
    } else if (position == 2) {
        view = layoutInflater.inflate(R.layout.videos_fragment, null);
    }

    // View einblenden
    viewPager.addView(view, 0);

    return view;
}

@Override
public void destroyItem(View container, int position, Object object) {
    // ViewPager
    ViewPager viewPager = (ViewPager) container;
    // View
    View view = (View) object;

    // View löschen
    viewPager.removeView(view);
}

@Override
public void finishUpdate(View container) {}

@Override
public boolean isViewFromObject(View view, Object object) {
    View _view = (View) object;
    return view == _view;
}

@Override
public Parcelable saveState() {
    return null;
}

@Override
public void restoreState(Parcelable state, ClassLoader loader) {}
 }

ここで、ビューページャーによって現在フォーカスされているビューを取得したいと思います。getChildAt(x)を試しましたが、機能しません。

いくつかの例がありますか、または現在のビューを取得する方法について何か考えがありますか?

ありがとう

4

11 に答える 11

89

PagerAdapter.setPrimaryItemメソッドをオーバーライドすることで、現在アクティブなオブジェクト (View、Fragment など) を保存できます。例えば:

private View mCurrentView;

@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
    mCurrentView = (View)object;
}
于 2011-12-26T20:01:48.813 に答える
41

instantiateItem メソッドで、作成したビューにタグを追加できます。

view.setTag(position);

後で、次の方法で現在選択されているビューにアクセスできます。

mPager.findViewWithTag(mPager.getCurrentItem());
于 2012-06-24T09:57:27.663 に答える
41

にリスナーを登録する必要がありますViewPager

pager.setOnPageChangeListener(new MyPageChangeListener()); 

スタブ リスナーを拡張して、リスナーをカスタマイズする必要があります。

private int focusedPage = 0;
private class MyPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
    @Override
    public void onPageSelected(int position) {
        focusedPage = position;
    }
}

これは、互換性ライブラリの ViewPager.java ソース コードを調べて見つけました。たとえば catch など、もっとできることがあると読みましたonPageScrollStateChanged

アダプターを作成するために、このブログ投稿のコードを使用しました。あなたは見てみたいかもしれません。

于 2011-07-25T16:48:27.713 に答える
4

最近、この正確なソリューションを実装する必要がありました。これが私がやった方法です:

Map<Integer, Object> views = Maps.newHashMap();

@Override
public Object instantiateItem(View container, int position) {
  /* Create and add your View here */
  Object result = ???

  views.put(position, result);
  return result;
}

@Override
public void destroyItem(View container, int position, Object object) {
  /** Remove your View here */

  views.remove(position);
}

protected View findViewForPosition(int position) {
  Object object = views.get(position);
  if (object != null) {
    for (int i = 0; i < getChildCount(); i++) {
      View view = getChildAt(i);
      if (isViewFromObject(view, object)) {
        return view;
      }
    }
  }
  return null;
}
于 2011-11-08T15:13:23.620 に答える
2

これを試して:

public View getCurrentView(ViewPager pager) {
    for (int i = 0; i < pager.getChildCount(); i++) {
        View child = pager.getChildAt(i);
        if (child.getX() <= pager.getScrollX() + pager.getWidth() && 
            child.getX() + child.getWidth() >= pager.getScrollX() + pager.getWidth()) {
            return child;
         }
     }
     return getChildAt(0);
}
于 2012-11-20T05:23:40.000 に答える
1

焦点を絞ったビューを取得するには、次の方法を使用します。

ViewPager に追加する前にビューを膨らませると、タグを設定します。次に、このタグをチェックします。

private View getCurrentView()
{
    for (int i = 0; i < pager.getChildCount(); i++)
    {
        View v = pager.getChildAt(i);
        if (v != null)
        {
            if (v.getTag().equals(pageList.get(pager.getCurrentItem()).getTag())) return v;
            // pageList is a list of pages that I pass to page adapter
        }
    }
    return null;
}
于 2012-02-14T11:02:41.530 に答える
0

与えられた答えは私にはあまり適していませんでした.それらはすべて望ましくない副作用を持っています. 不要な変数を追加する必要がある (きれいなコードが好き) か、Android フレームワーク自体を回避する必要があります。

私のソリューションは、ViewPager 内のすべてのオブジェクトの配列リストにアクセスし、ViewPager で現在選択されているオブジェクトを返すリフレクションに基づいています。副作用はほとんどなく (リフレクションが遅く、既存のクラスをサブクラス化する)、コードをきれいに保ちます。

public class ViewPagerEx extends ViewPager {

    private static final String TAG = ViewPagerEx.class.getSimpleName();

    public ViewPagerEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ViewPagerEx(Context context) {
        super(context);
    }

    public Object getCurrentObject() {
        try {
            final Field itemsField = ViewPager.class.getDeclaredField("mItems");
            itemsField.setAccessible(true);

            final ArrayList<Object> items = (ArrayList<Object>) itemsField.get(this);

            final int currentItemIndex = getCurrentItem();
            if (currentItemIndex < 0 || currentItemIndex >= items.size()) {
                return null;
            }

            final Object infoItem = items.get(getCurrentItem());

            final Class<?> itemInfoClass = findItemInfoClass(ViewPager.class.getDeclaredClasses());

            final Field objectField = itemInfoClass.getDeclaredField("object");
            objectField.setAccessible(true);
            return objectField.get(infoItem);

        } catch (NoSuchFieldException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalArgumentException e) {
            Log.e(TAG, e.toString());
        } catch (IllegalAccessException e) {
            Log.e(TAG, e.toString());
        }

        return null;
    }

    private Class<?> findItemInfoClass(final Class<?>[] classes) throws IllegalArgumentException {
        for (int i = 0; i < classes.length; i++) {
            if (classes[i].getSimpleName().equals("ItemInfo")) {
                return classes[i];
            }
        }

        throw new IllegalArgumentException("cannot find class ItemInfo");
    }
}
于 2012-08-17T14:50:06.993 に答える
0

あなたの中にFragmentStatePagerAdapter

    private View mCurrentView;

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        Fragment f = (Fragment) object;
        mCurrentView = f.getView();
    }
于 2016-03-17T18:37:32.103 に答える
-1

注意深く調べると、ViewPagerによって保存されるビューは最大3つです。あなたは簡単に現在のビューを取得することができます

view     = MyActivity.mViewPager.getChildAt(1);
于 2012-12-12T22:12:54.890 に答える
-1

何か不足していますか?ViewGroup 内には 3 つの子しかないため、要約すると次のようになります。

int current = viewPager.getCurrentItem();
int childCount = viewPager.getChildCount();
// If there's a single page or we're at the beginning, return the first view
if (childCount == 1 || current == 0) {
  return viewPager.getChildAt(0);
} else { //For any other case, we want the second child. This is either the last page or the page in the middle for any other case.
  return viewPager.getChildAt(1);
}
于 2014-01-09T00:29:05.330 に答える