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) {}
}
今、私はviewpagerによって現在のフォーカスされたビューを取得したい。 getChildAt(x)を試しましたが、機能しません。
いくつかの例はありますか、または現在のビューを取得する方法はありますか?
ありがとう
PagerAdapter.setPrimaryItem メソッドをオーバーライドすることにより、現在アクティブなオブジェクト(View、Fragmentなど)を保存することができます。例えば:
private View mCurrentView;
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
mCurrentView = (View)object;
}
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ソースコードを見て、これを見つけました。キャッチonPageScrollStateChanged
など、もっとできることがあると読みました。
アダプターを構築するために、コードを使用しました このブログ投稿 。ご覧になりたいかもしれません。
InstantiateItemメソッドで作成されたビューにタグを追加できます。
view.setTag(position);
後で、次の方法で現在選択されているビューにアクセスできます。
mPager.findViewWithTag(mPager.getCurrentItem());
最近、この正確なソリューションを実装する必要がありました。これが私がやった方法です:
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;
}
これを試して:
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);
}
フォーカスされたビューを取得するには、この方法を使用します。
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;
}
このコードを使用できます
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Toast.makeText(getContext(), String.valueOf(position), Toast.LENGTH_SHORT).show();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
与えられた答えは私にはあまり適していませんでした。それらはすべて望ましくない副作用があります。不要な変数を追加する必要がある(クリーンコードが好き)か、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");
}
}
FragmentStatePagerAdapter
内:
private View mCurrentView;
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment f = (Fragment) object;
mCurrentView = f.getView();
}