彼らのアドバイスに:ホイールは便利ですが、前提は、ホイールを使用することですが:あなたは複雑な機能の数をパッケージ化していない場合、彼らは基本的な方法、または他の誰かであっても最高のホイールで書き込みます、とき彼らのプロジェクト経験と車輪のない同じ場所には、それだけで何もできないか、他の人のソースコードを変更するには、当然のことながら、自分の知識や自分のアイデア車輪が簡単に最善かつシンプルで、ソースコードを変更することができます適用するパッケージを読み取ることができます。
1.アイデアの実現
二つのオプション:
(1)同様にgetCountアダプタ内()メソッドは、Integer.MAX_VALUEを返します。
プリペンド(2)データがリストの第一の端部に挿入され、最後のデータのリストに、円形の錯覚を引き起こします
2.実現
2.1プログラム:同様にgetCount()はInteger.MAX_VALUEを返します
2.1.1 ViewPager無限ループ
アダプタViewPager同様にgetCountの方法では、リターンは多数、理論的には無制限のスライドをInteger.MAX_VALUEの。実際のサイクルの完全なリストを表示し、そして0実位置一覧表示データから、無限ループの回転の錯覚を作成します。最初のページは左ViewPagerサイクルにスライドさせることができないので、私たちは最初は左にスライドすることができるように、mViewPager.setCurrentItem(Integer.MAX_VALUEの/ 2)によって提供される場所を選択しなければならないが、最初のページは、値%を表示するようにデータ数== 0。ANRは、ときsetCurrentItem()はInteger.MAX_VALUEを設定した後に起こるので、ここでカスタム多数が優れている使用しているため、ここで私は500でした
//当前选中页
private int currentPosition;
//数据项个数
private List<Integer> itemList;
public static final int mLooperCount = 500;
//设置当前选中的item
currentPosition = getStartItem();
viewPager1.setCurrentItem(currentPosition1);
private int getStartItem() {
if(getRealCount() == 0){
return 0;
}
// 我们设置当前选中的位置为Integer.MAX_VALUE / 2,这样开始就能往左滑动
// 但是要保证这个值与getRealPosition 的 余数为0,因为要从第一页开始显示
int currentItem = getRealCount() * BannerAdapter.mLooperCount / 2;
if(currentItem % getRealCount() ==0 ){
return currentItem;
}
// 直到找到从0开始的位置
while (currentItem % getRealCount() != 0){
currentItem++;
}
return currentItem;
}
//获取数据项个数
private int getRealCount() {
return itemList == null ? 0 : itemList.size();
}
复制代码
アダプタは、単に同様にgetCount()、その他の動作は正常動作している(ここでは、我々は特定の値に変更)はInteger.MAX_VALUEを返すことができます。
@Override
public int getCount() {
return getRealCount() * mLooperCount;
}
复制代码
2.1.2追加カルーセル機能
メソッドを使用してハンドラpostDelayed
private Handler mHandler = new Handler();
@Override
protected void onResume() {
super.onResume();
//开始轮播
mHandler.postDelayed(mLoopRunnable, mDelayedTime);
}
@Override
protected void onPause() {
super.onPause();
//停止轮播
mHandler.removeCallbacks(mLoopRunnable);
}
复制代码
private final Runnable mLoopRunnable = new Runnable() {
@Override
public void run() {
if (mIsAutoPlay) {
//方案一
currentPosition1 = viewPager1.getCurrentItem();
currentPosition1++;
if (currentPosition1 == bannerAdapter.getCount() - 1) { //滑到最后一个时
currentPosition1 = 0; //切换到第0个
viewPager1.setCurrentItem(currentPosition1, false);
mHandler.postDelayed(this, mDelayedTime);
} else {
viewPager1.setCurrentItem(currentPosition1);
mHandler.postDelayed(this, mDelayedTime);
}
} else {
mHandler.postDelayed(this, mDelayedTime);
}
}
};
复制代码
2.1.3 Integer.MAX_VALUEの論争
一部の人々は、我々はこの記事を参照することができ、それがメモリに影響を与えるだろうと思うかもしれ無制限のカルーセルInteger.MAX_VALUEの論争は、(ソースコードを参照してください)AndroidのViewPagerの疑問を解決することができるようになります。
2.1.4注意
setCurrentItem()、それはより多くの方が良いに設定されているときに使用Integer.MAX_VALUEのANRが起こります。コードでは私はgetRealCount()* 500にこの値を返すように変更しました、私は間違っていなかったInteger.MAX_VALUEののリターンがある場合は、あなた自身の記事を変更します。
2.2オプションII:いずれかの端部、2つのデータ項目
2.2.1 ViewPager無限ループ
2、1の番号が付けられ、私たちは新しいリストを作成します、長さは最後の3つのデータの先頭に挿入され、実際の2のリストの長さで、3件のデータがあると仮定し、1における第1の表面の終了後にデータを挿入し、新しいです0:00によってviewpager上の位置にスライドするときのリストは、3,1,2,3,1となるsetCurrentItem(int item,boolean smoothScroll)
ので、同様にスライド4は、ページはこの方法により位置1に切り換えられる位置に、ページ3位を切り替える方法それは私たちに無限ループという感じを与えます。
private int currentPosition2;
private void initData2() {
itemList2 = new ArrayList<>();
itemList2.add(R.drawable.ic_pic4);
itemList2.add(R.drawable.ic_pic1);
itemList2.add(R.drawable.ic_pic2);
itemList2.add(R.drawable.ic_pic3);
itemList2.add(R.drawable.ic_pic4);
itemList2.add(R.drawable.ic_pic1);
bannerAdapter2 = new BannerAdapter2(itemList2);
viewPager2.setAdapter(bannerAdapter2);
currentPosition2 = 1;
viewPager2.setCurrentItem(currentPosition2);
viewPager2.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
currentPosition2 = i;
}
@Override
public void onPageScrollStateChanged(int state) {
//验证当前的滑动是否结束
if (state == ViewPager.SCROLL_STATE_IDLE) {
if (currentPosition2 == 0) {
viewPager2.setCurrentItem(itemList2.size() - 2, false);//切换,不要动画效果
} else if (currentPosition2 == itemList2.size() - 1) {
viewPager2.setCurrentItem(1, false);//切换,不要动画效果
}
}
}
});
}
复制代码
2.2.2追加カルーセル機能
private Handler mHandler2 = new Handler();
@Override
protected void onResume() {
super.onResume();
//开始轮播
mHandler2.postDelayed(mLoopRunnable2, mDelayedTime);
}
@Override
protected void onPause() {
super.onPause();
//停止轮播
mHandler2.removeCallbacks(mLoopRunnable2);
}
复制代码
private final Runnable mLoopRunnable2 = new Runnable() {
@Override
public void run() {
if (mIsAutoPlay) {
//方案二:多添两条数据
currentPosition2 = viewPager2.getCurrentItem();
currentPosition2++;
//不需要为了循环轮播来判断是否到达最后一页,在监听器中已经为我们做了此操作
viewPager2.setCurrentItem(currentPosition2);
mHandler2.postDelayed(this, mDelayedTime);
} else {
mHandler2.postDelayed(this, mDelayedTime);
}
}
};
复制代码
所定の場所にスライドしたときに別のプログラムが最後のものであるとスライドのページの添字0は最後に切り替わると、次のページへの切り替えは、1とラベル
2.3比較
ファントはまだ西が希薄スライド4の位置は、我々は唯一の1を配置し、それを切り替えるsetCurrentItem(int型の項目、ブールsmoothScroll)メソッドを渡したときため、2番目のオプションは、アニメーションを切り替えている:記事の言いました無限ループの効果ではなく、見つからないようにするために、2番目のパラメータsmoothScrollはfalseに設定されているので、そこにはスイッチングアニメーションが硬く、その結果、ではありませんので、これを行います。
もともとオプションIIを(行にする方法を考える)を達成するために思ったが、好奇心は私がどのように硬い最後の次の見たいと思って作られたが、その効果を鈍ら見つけることができませんでした。我々は第四、再び時間の期間を開けにスライドするとき、我々は実際に第五にスライドさonPageScrollStateChanged()における方法であって、そうでアニメーションの最後の状態を監視するため、その画像は、我々はこの尾に追加することです映画ではなく、それが実際に判断されたインデックス位置0、およびこのリスナーでは、最後の1でITEMLISTがあるとき、我々は密かにそれに切り替え、アニメーションなしsetCurrentItem()モードに合格しています添字1位、それが絵の中にスライドしていることのCurrentItem ++方法によって再びハンドラスライドは効果でも、2とラベル付けされている場合、その鈍らどのような効果が存在しません。私は4つのマップの合計を置くの下には、我々はの効果を詳しく見てとることができます。
3.まとめ
それはViewPager無制限のカルーセルを達成するための最も基本的な方法のためにすべてです。特定のコードを参照してくださいGitHubのを。
実際には、我々はそこにバナーインジケータインジケータの共通のビューを持っている私が実際に使用したり、(それは、下のドットである)まだファントは西洋希薄同じであるが、カスタムインジケータを、それは本当に便利なので、パッケージも非常にシンプルである場合には、が、私はまだ、彼らは印象の下に次の記事を参照し、深めているように、パッケージの再記録処理を見てみたいです。
4.参考記事
論争Integer.MAX_VALUEのアンドロイドViewPager無制限のカルーセル(ソースを参照してください)
広告BannerView模倣MeizuのアプリケーションViewPagerシリーズ
アンドロイドはViewPager無制限のカルーセル空白のバグの理由と解決策(Integer.MAX_VALUEの実装)を使用しています
ます。https://juejin.im/post/5d08b8a251882559ed71d789で再現