Googleによって文書化されているように、GalleryクラスはAPIレベル16で非推奨になりました。このウィジェットはサポートされなくなりました。他の水平スクロールウィジェットには、サポートライブラリのHorizontalScrollViewとViewPagerが含まれます。そこで、Galleryクラスの代わりにViewPagerを使用しました。
最終的にテキストの説明を含む無限スクロール画像ViewPagerを達成するという私の目標。以下のコードを使用して、各画像を説明するテキストを含む画像ViewPagerを作成しましたが、ViewPagerに無限スクロールを適用するにはどうすればよいですか?
私はこれまでViewPagerを使用したことがないので、可能であれば詳細なコードを提供してみてください。
activity_main.xml:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical">
<Android.support.v4.view.ViewPager
Android:id="@+id/myimagepager"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</LinearLayout>
custom_pager.xml:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
Android:gravity="center_horizontal">
<ImageView
Android:id="@+id/myimage"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_margin="5dp"
Android:layout_weight="2" />
<TextView
Android:id="@+id/image_text"
Android:layout_width="fill_parent"
Android:layout_height="0dp"
Android:layout_weight="1"/>
</LinearLayout>
ImagePager:
public class ImagePager extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra, stringArray );
ViewPager myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
}
private int imageArra[] = { R.drawable.a, R.drawable.b,R.drawable.c,
R.drawable.d,R.drawable.e,R.drawable.f,
R.drawable.g, R.drawable.h, R.drawable.i};
private String[] stringArray = new String[] { "Image a", "Image b","Image c"
"Image d","Image e","Image f",
"Image g","Image h","Image i"};
}
ImagePagerAdapter:
public class ImagePagerAdapter extends PagerAdapter {
Activity activity;
int imageArray[];
String[] stringArray;
public ImagePagerAdapter(Activity act, int[] imgArra, String[] stringArra) {
imageArray = imgArra;
activity = act;
stringArray = stringArra;
}
public int getCount() {
return imageArray.length;
}
public Object instantiateItem(View collection, int position) {
LayoutInflater inflater = (LayoutInflater)collection.getContext
().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_pager, null);
ImageView im=(ImageView) layout.findViewById(R.id.myimage);
im.setImageResource(imageArray[position]);
TextView txt=(TextView) layout.findViewById(R.id.image_text);
txt.setText(stringArray[position]);
((ViewPager) collection).addView(layout, 0);
return layout;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
@Override
public Parcelable saveState() {
return null;
}
}
同じ問題 がありましたが、それを解決する方法を見つけることができました-コードは github にあります。
クラス InfiniteViewPager および InfinitePagerAdapter をプロジェクトにコピーすると、いくつかの小さな変更を加えるだけで、無限(ラップ)スクロールを実現できます。
アクティビティで、PagerAdapterをInfinitePagerAdapter
でラップします。
PagerAdapter adapter = new InfinitePagerAdapter(new ImagePagerAdapter(this, imageArra, stringArray));
アクティビティXMLのViewPagerをInfiniteViewPager
に変更します。
<com.antonyt.infiniteviewpager.InfiniteViewPager
Android:id="@+id/myimagepager"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
クラスの名前は任意の名前に変更できます。このコードは、少なくとも3ページある場合にのみ機能します(サンプルコードには9ページあるため、問題なく機能します)。
私の解決策はもっと簡単だと思います。
画像構造の配列への注意:
Item 0 => last image
Item count()-1 => first image
トリックはonPageScrollStateChanged
にあります:
ユーザーが最後のアイテムにスクロールすると、ページャーはアニメーションなしで最初の画像にジャンプします(位置= 1)
ユーザーが最初のアイテムにスクロールすると、ページャーはアニメーションなしで最後の画像にジャンプします(位置=カウント-2)
public class InfiniteScrollingActivity extends ActionBarActivity {
private ViewPager pager;
private MyAdapter adapter;
int[] promoImageIds = new int[]{R.drawable.cover6, R.drawable.cover1, R.drawable.cover2, R.drawable.cover3, R.drawable.cover4, R.drawable.cover5, R.drawable.cover6, R.drawable.cover1 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_test);
adapter = new MyAdapter(getSupportFragmentManager(), promoImageIds);
pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
pager.setCurrentItem( 1 );
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
Log.v( "onPageSelected", String.valueOf( index ) );
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// Log.v("onPageScrolled", "");
}
@Override
public void onPageScrollStateChanged(int state) {
Log.v("onPageScrollStateChanged", String.valueOf(state));
if (state ==ViewPager.SCROLL_STATE_IDLE) {
int index = pager.getCurrentItem();
if ( index == 0 )
pager.setCurrentItem( adapter.getCount() - 2, false );
else if ( index == adapter.getCount() - 1 )
pager.setCurrentItem( 1 , false);
}
}
});
}
public static class MyAdapter extends FragmentPagerAdapter {
int[] promoImageIds;
public MyAdapter(FragmentManager fm, int[] promoImageIds){
super(fm);
this.promoImageIds = promoImageIds;
}
@Override
public int getCount(){
return promoImageIds.length;
}
@Override
public Fragment getItem(int position) {
return PromoFragment.newInstance( promoImageIds[position] );
}
}
public static class PromoFragment extends Fragment
{
int imageID;
static PromoFragment newInstance( int imageID)
{
PromoFragment f = new PromoFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt( "imageID", imageID );
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
imageID = getArguments() != null ? getArguments().getInt( "imageID" ) : null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
ImageView v = (ImageView) inflater.inflate(R.layout.fragment_image, container, false);
v.setImageResource( imageID );
return v;
}
}
}
私はすでに簡単なトリックを作ることによって方法を見つけました、私はそれがあなたに役立つことを願っています
import Java.util.ArrayList;
import Android.os.Bundle;
import Android.app.Activity;
import Android.support.v4.view.ViewPager;
import Android.support.v4.view.ViewPager.OnPageChangeListener;
import Android.util.Log;
public class ImagePager extends Activity {
String[] stringArray;
int[] imageArra;
ViewPager myPager;
Boolean isScrooled = false;
// use this array yo understand swipe left or right ?
ArrayList<Float> pos = new ArrayList<Float>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// put empty view at the beginnig and to end
imageArra = new int[] { 0, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher, 0 };
// put empty string at the beginnig and to end
stringArray = new String[] { "", "Image a", "Image b", "Image c",
"Image d", "Image e", "Image f", "Image g", "Image h",
"Image i", "" };
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra,
stringArray);
myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(1);
myPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.v("onPageSelected", String.valueOf(arg0));
pos.clear();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
try {
// while scrolling i add ever pos to array
pos.add(arg1);
// if pos.get(0) > pos.get(pos.size() - 1)
// <----- swipe <-----
// we should check isScroll because setCurrent item is not a croll ?
if (pos.size() > 0)
if (arg0 == imageArra.length - 1
& pos.get(0) > pos.get(pos.size() - 1)
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(1, false);
} catch (Exception e) {
Log.v("hata",
"<----- swipe <----- " + e.toString());
}
}
// ----> swipe ---->
else if (arg0 == 0
& pos.get(0) < pos.get(pos.size() - 1)
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(imageArra.length - 1,
false);
} catch (Exception e) {
Log.v("hata",
"----> swipe ----> " + e.toString());
}
} else if (arg0 == 0 & pos.size() == 1
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(imageArra.length - 1,
false);
} catch (Exception e) {
Log.v("hata",
"----> swipe ----> " + e.toString());
}
}
} catch (Exception e) {
Log.v("hata", e.toString());
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.v("onPageScrollStateChanged", String.valueOf(arg0));
// set is scrolling
isScrooled = true;
}
});
}
}
[編集1]
import Java.util.ArrayList;
import Android.app.Activity;
import Android.os.Bundle;
import Android.support.v4.view.ViewPager;
import Android.support.v4.view.ViewPager.OnPageChangeListener;
import Android.util.Log;
public class ImagePager extends Activity {
String[] stringArray;
int[] imageArra;
ViewPager myPager;
int scrollState;
Boolean isFirstVisitEnd= true,isFirstVisitBegin = true;
ArrayList<Integer> pos = new ArrayList<Integer>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageArra = new int[] { 0,R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher, 0 };
stringArray = new String[] {"","Image a", "Image b", "Image c",
"Image d", "Image e", "Image f", "Image g", "Image h",
"Image i", "" };
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra,
stringArray);
myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(1);
myPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.v("onPageSelected", String.valueOf(arg0));
pos.clear();
if (arg0 == imageArra.length - 1)
isFirstVisitEnd = false;
else
isFirstVisitEnd = true;
if (arg0 == 0)
isFirstVisitBegin = false;
else
isFirstVisitBegin = true;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
try {
pos.add(Integer.valueOf(arg2));
if (pos.size() > 0) {
//Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitEnd: "+String.valueOf(isFirstVisitEnd.booleanValue()) );
// <----- swipe <-----
if (arg0 == imageArra.length - 2& (pos.get(pos.size() - 1) -pos.get(0) < 100)& scrollState == 2 & isFirstVisitEnd == false) {
myPager.setCurrentItem(1, false);
}
//Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitbegin: "+String.valueOf(isFirstVisitBegin.booleanValue()) );
if (arg0 == 0 & (pos.get(pos.size() - 1) -pos.get(0) > -100)& scrollState == 2 & isFirstVisitBegin == false) {
myPager.setCurrentItem(imageArra.length - 2, false);
}
}
} catch (Exception e) {
Log.v("hata", e.toString());
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.v("onPageScrollStateChanged", String.valueOf(arg0));
scrollState =arg0;
}
});
}
}
Shlomi Hasin と antonyt の回答に基づいて、コレクションを変更せずに別の解決策を見つけました。
ViewPager yourPager;
PagerAdapter yourAdapter;
//....
EndlessPagerAdapter endlessPagerAdapter = new EndlessPagerAdapter(yourAdapter, yourPager);
yourPager.setAdapter(endlessPagerAdapter);
yourPager.setCurrentItem(1);//for correct first page
フルクラス:
public class EndlessPagerAdapter extends PagerAdapter {
private PagerAdapter adapter;
public EndlessPagerAdapter(PagerAdapter adapter, ViewPager viewPager) {
this.adapter = adapter;
viewPager.addOnPageChangeListener(new SwapPageListener(viewPager));
}
@Override
public int getCount() {
return adapter.getCount() + 2;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (adapter.getCount() < 2) {
adapter.instantiateItem(container, position);
}
int newPosition;
if (position == 0) {
newPosition = adapter.getCount() - 1;
} else if (position >= getCount() - 1) {
newPosition = 0;
} else {
newPosition = position - 1;
}
return adapter.instantiateItem(container, newPosition);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
adapter.destroyItem(container, position, object);
}
@Override
public void finishUpdate(ViewGroup container) {
adapter.finishUpdate(container);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return adapter.isViewFromObject(view, object);
}
@Override
public void restoreState(Parcelable bundle, ClassLoader classLoader) {
adapter.restoreState(bundle, classLoader);
}
@Override
public Parcelable saveState() {
return adapter.saveState();
}
@Override
public void startUpdate(ViewGroup container) {
adapter.startUpdate(container);
}
@Override
public CharSequence getPageTitle(int position) {
return adapter.getPageTitle(position);
}
@Override
public float getPageWidth(int position) {
return adapter.getPageWidth(position);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
adapter.setPrimaryItem(container, position, object);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
adapter.unregisterDataSetObserver(observer);
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
adapter.registerDataSetObserver(observer);
}
@Override
public void notifyDataSetChanged() {
adapter.notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
return adapter.getItemPosition(object);
}
private class SwapPageListener implements ViewPager.OnPageChangeListener {
private ViewPager viewPager;
SwapPageListener(ViewPager viewPager) {
this.viewPager = viewPager;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
PagerAdapter pagerAdapter = viewPager.getAdapter();
if (pagerAdapter != null) {
int itemCount = pagerAdapter.getCount();
if (itemCount < 2) {
return;
}
int index = viewPager.getCurrentItem();
if (index == 0 ) {
viewPager.setCurrentItem(itemCount - 2, false);
} else if (index == itemCount - 1) {
viewPager.setCurrentItem(1, false);
}
}
}
}
}}
仕組み:
いくつかのコレクションがあります
次に、それに2つのアイテムを追加します
最後の位置に最初の要素を表示し、最初の位置に最後の要素を表示します
イベントにリスナーを追加し、ページを4から1および0から3に交換します
それで全部です。
そこにアニメーションや重いレイアウトを適用することはお勧めしません。要素が入れ替わると遅れる可能性があります(たぶん、遅れは発生しませんでした)
また、このアダプタをページャーに複数回設定したり、SwapPageListenerを外部クラスに移動して初期化ブロックに設定したりしないでください。
RecyclerViewPager 実装infinite scrolling
そしてギャラリーのようにスクロールできます。
日を伴う無限スクロールの場合、ページャーに適切なフラグメントがあることが重要であるため、これに私の答えをページに書き込みました( Viewpager in Android to switch endlessly )
それは非常にうまく機能しています!上記の答えは、私がそれを機能させたかったので、私には機能しませんでした。
if ((pagerBottom.getCurrentItem() + 1) == (sliderimageDetails.size())) {
pagerBottom.setCurrentItem(0);
} else {
pagerBottom.setCurrentItem((pagerBottom.getCurrentItem() + 1));
}