独自のAndroidスライドを作成
androidアプリケーションでは、自動切り替えや手動切り替え、インジケータなど、画像や広告のマルチキャスト効果が使われることが多い.だからnineoldandroidを使う必要もなく、アニメーションの効果が使えないことも多く、他のレイアウトと衝突するなどのシリーズの問題があるので、自分のandroidスライダを作る必要があります.
まず、ViewPagerを使って効果を実現することを考えています.ViewPagerは画像の切り替えができます.そして、手動でしかできません.他の効果は少しずつ追加しなければなりません.例えば、マルチキャスト効果、インジケータ、自動切り替え、アニメーション効果などです.次は一つ一つの問題を解決します.
ローテーション効果原生を実現するViewPagerはローテーション効果をサポートしていないので、最初のページにスライドしたり、最後のページにスライドしたりすると、これ以上スライドできません.そんなに快適ではありません.今、appを作ってもローテーション効果をサポートしないわけにはいきません.この問題はネット上で解決策があります.原生のViewPagerを変更する必要はありません.PagerAdapterを書き直すだけでいいです.キーコードを見てください.
実は輪番は偽物ですが、偽物で本物を乱す効果もあります.countの設置は十分大きく、普通の人はこんなに滑れませんが、いずれにしても、これは解決策として使われています.
効果図の簡単なマルチキャスト効果が出てきましたが、効果はまだ明らかではありません.次にインジケータを追加します.
名前の通りにインジケータを追加し、ピクチャの個数を提示し、現在のピクチャの位置を識別します.コードでシェイプを描くことも、ピクチャを使用することもできます.次に、スライダをViewにカプセル化し、SliderLayoutを新規作成します.
xmlで追加
コードでの使用
効果のデモはここでインジケータはすでにokになって、次は自動的に切り替えます
自動切替用Handler実現タイマー
SliderLayoutレイアウトの変更により自動ローテーションの効果が追加されました
最后にいろいろなアニメを追加して、ネット上の例は比较的に多くて、简単にみんなにコツを教えます
これはぜひご理解ください.慕課網千変万化のViewPagerチュートリアルの簡単なプレゼンテーションをお勧めします.
完全demoはgithub SliderLayoutにアップロードされました
まず、ViewPagerを使って効果を実現することを考えています.ViewPagerは画像の切り替えができます.そして、手動でしかできません.他の効果は少しずつ追加しなければなりません.例えば、マルチキャスト効果、インジケータ、自動切り替え、アニメーション効果などです.次は一つ一つの問題を解決します.
ローテーション効果原生を実現するViewPagerはローテーション効果をサポートしていないので、最初のページにスライドしたり、最後のページにスライドしたりすると、これ以上スライドできません.そんなに快適ではありません.今、appを作ってもローテーション効果をサポートしないわけにはいきません.この問題はネット上で解決策があります.原生のViewPagerを変更する必要はありません.PagerAdapterを書き直すだけでいいです.キーコードを見てください.
public class LoopPagerAdapter extends PagerAdapter {
private List<View> views;
public LoopPagerAdapter(List<View> views) {
this.views = views;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;//2147483647
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = views.get(position % views.size());
if (container.equals(view.getParent())) {
container.removeView(view);
}
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
実は輪番は偽物ですが、偽物で本物を乱す効果もあります.countの設置は十分大きく、普通の人はこんなに滑れませんが、いずれにしても、これは解決策として使われています.
public class MainActivity extends ActionBarActivity {
private ViewPager pager;
private LoopPagerAdapter loopPagerAdapter;
private List<View> views = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pager = (ViewPager) findViewById(R.id.pager);
views.add(getView(R.mipmap.img1));
views.add(getView(R.mipmap.img2));
views.add(getView(R.mipmap.img3));
loopPagerAdapter = new LoopPagerAdapter(views);
pager.setAdapter(loopPagerAdapter);
// item Integer.MAX_VALUE , ok
// ,
pager.setCurrentItem(Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % views.size());
}
private View getView(int res) {
ImageView imageView = new ImageView(this);
// glide setImageResource
Glide.with(this).load(res).into(imageView);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return imageView;
}
効果図の簡単なマルチキャスト効果が出てきましたが、効果はまだ明らかではありません.次にインジケータを追加します.
名前の通りにインジケータを追加し、ピクチャの個数を提示し、現在のピクチャの位置を識別します.コードでシェイプを描くことも、ピクチャを使用することもできます.次に、スライダをViewにカプセル化し、SliderLayoutを新規作成します.
public class SliderLayout extends RelativeLayout {
private ViewPager pager;
//
private LinearLayout indicatorContainer;
private Drawable unSelectedDrawable;
private Drawable selectedDrawable;
public SliderLayout(Context context) {
super(context);
initView();
}
public SliderLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public SliderLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
// pager
pager = new ViewPager(getContext());
// viewpager SliderLayout
addView(pager);
// indicatorContainer
indicatorContainer = new LinearLayout(getContext());
RelativeLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// ,
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
// margin
params.setMargins(dpToPx(10), dpToPx(10), dpToPx(10), dpToPx(10));
// SliderLayout
addView(indicatorContainer, params);
//
LayerDrawable unSelectedLayerDrawable;
LayerDrawable selectedLayerDrawable;
GradientDrawable unSelectedGradientDrawable;
unSelectedGradientDrawable = new GradientDrawable();
unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
unSelectedGradientDrawable.setColor(Color.GRAY);
unSelectedGradientDrawable.setSize(dpToPx(8), dpToPx(8));
unSelectedLayerDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
unSelectedDrawable = unSelectedLayerDrawable;
//
GradientDrawable selectedGradientDrawable;
selectedGradientDrawable = new GradientDrawable();
selectedGradientDrawable.setShape(GradientDrawable.OVAL);
selectedGradientDrawable.setColor(Color.RED);
selectedGradientDrawable.setSize(dpToPx(8), dpToPx(8));
selectedLayerDrawable = new LayerDrawable(new Drawable[]{selectedGradientDrawable});
selectedDrawable = selectedLayerDrawable;
}
//
public void setViewRes(List<Integer> viewRes) {
List<View> views = new ArrayList<>();
for (Integer res : viewRes) {
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(getContext()).load(res).into(imageView);
views.add(imageView);
}
setViews(views);
}
//
public void setViewUrls(List<String> urls) {
List<View> views = new ArrayList<>();
for (String url : urls) {
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(getContext()).load(url).into(imageView);
views.add(imageView);
}
setViews(views);
}
// View
public void setViews(final List<View> views) {
// ,
for (int i = 0; i < views.size(); i++) {
ImageView indicator = new ImageView(getContext());
indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
indicator.setPadding(dpToPx(3), dpToPx(3), dpToPx(3), dpToPx(3));
indicatorContainer.addView(indicator);
}
LoopPagerAdapter pagerAdapter = new LoopPagerAdapter(views);
pager.setAdapter(pagerAdapter);
// item Integer.MAX_VALUE , ok
// ,
int currentItem = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % views.size();
pager.setCurrentItem(currentItem);
switchIndicator(currentItem % views.size());
//
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switchIndicator(position % views.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/** * * @param currentPosition */
private void switchIndicator(int currentPosition) {
for (int i = 0; i < indicatorContainer.getChildCount(); i++) {
((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == currentPosition ? selectedDrawable : unSelectedDrawable);
}
}
/** * dp px * @param dp dp * @return px */
private int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics) + 0.5);
}
}
xmlで追加
<com.example.dongjunkun.myapplication.SliderLayout
android:id="@+id/sliderLayout"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
コードでの使用
public class MainActivity extends ActionBarActivity {
private SliderLayout sliderLayout;
private List<Integer> viewRes = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sliderLayout = (SliderLayout) findViewById(R.id.sliderLayout);
viewRes.add(R.mipmap.img1);
viewRes.add(R.mipmap.img2);
viewRes.add(R.mipmap.img3);
sliderLayout.setViewRes(viewRes);
}
}
効果のデモはここでインジケータはすでにokになって、次は自動的に切り替えます
自動切替用Handler実現タイマー
public class SliderLayout extends RelativeLayout implements android.os.Handler.Callback {
public static final int DELAY_MILLIS = 4000;
private ViewPager pager;
//
private LinearLayout indicatorContainer;
private Drawable unSelectedDrawable;
private Drawable selectedDrawable;
private int WHAT_AUTO_PLAY = 1000;
private Handler handler;
private boolean isAutoPlay = false;
public SliderLayout(Context context) {
super(context);
initView();
}
public SliderLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public SliderLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
handler = new Handler(this);
// pager
pager = new ViewPager(getContext());
// viewpager SliderLayout
addView(pager);
// indicatorContainer
indicatorContainer = new LinearLayout(getContext());
RelativeLayout.LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// ,
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
// margin
params.setMargins(dpToPx(10), dpToPx(10), dpToPx(10), dpToPx(10));
// SliderLayout
addView(indicatorContainer, params);
//
LayerDrawable unSelectedLayerDrawable;
LayerDrawable selectedLayerDrawable;
GradientDrawable unSelectedGradientDrawable;
unSelectedGradientDrawable = new GradientDrawable();
unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
unSelectedGradientDrawable.setColor(Color.GRAY);
unSelectedGradientDrawable.setSize(dpToPx(8), dpToPx(8));
unSelectedLayerDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
unSelectedDrawable = unSelectedLayerDrawable;
//
GradientDrawable selectedGradientDrawable;
selectedGradientDrawable = new GradientDrawable();
selectedGradientDrawable.setShape(GradientDrawable.OVAL);
selectedGradientDrawable.setColor(Color.RED);
selectedGradientDrawable.setSize(dpToPx(8), dpToPx(8));
selectedLayerDrawable = new LayerDrawable(new Drawable[]{selectedGradientDrawable});
selectedDrawable = selectedLayerDrawable;
}
//
public void setViewRes(List<Integer> viewRes) {
List<View> views = new ArrayList<>();
for (Integer res : viewRes) {
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(getContext()).load(res).into(imageView);
views.add(imageView);
}
setViews(views);
}
//
public void setViewUrls(List<String> urls) {
List<View> views = new ArrayList<>();
for (String url : urls) {
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
Glide.with(getContext()).load(url).into(imageView);
views.add(imageView);
}
setViews(views);
}
// View
public void setViews(final List<View> views) {
// ,
for (int i = 0; i < views.size(); i++) {
ImageView indicator = new ImageView(getContext());
indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
indicator.setPadding(dpToPx(3), dpToPx(3), dpToPx(3), dpToPx(3));
indicatorContainer.addView(indicator);
}
LoopPagerAdapter pagerAdapter = new LoopPagerAdapter(views);
pager.setAdapter(pagerAdapter);
// item Integer.MAX_VALUE , ok
// ,
int currentItem = Integer.MAX_VALUE / 2 - Integer.MAX_VALUE / 2 % views.size();
pager.setCurrentItem(currentItem);
switchIndicator(currentItem % views.size());
//
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switchIndicator(position % views.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
startAutoPlay();
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == WHAT_AUTO_PLAY) {
pager.setCurrentItem(pager.getCurrentItem() + 1, true);
handler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, DELAY_MILLIS);
}
return false;
}
/** * */
public void startAutoPlay() {
if (!isAutoPlay) {
handler.sendEmptyMessageDelayed(WHAT_AUTO_PLAY, DELAY_MILLIS);
isAutoPlay = true;
}
}
/** * */
public void stopAutoPlay() {
if (isAutoPlay) {
handler.removeMessages(WHAT_AUTO_PLAY);
isAutoPlay = false;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
stopAutoPlay();
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
startAutoPlay();
break;
}
return super.dispatchTouchEvent(ev);
}
/** * * * @param currentPosition */
private void switchIndicator(int currentPosition) {
for (int i = 0; i < indicatorContainer.getChildCount(); i++) {
((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == currentPosition ? selectedDrawable : unSelectedDrawable);
}
}
/** * dp px * * @param dp dp * @return px */
private int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics) + 0.5);
}
}
SliderLayoutレイアウトの変更により自動ローテーションの効果が追加されました
最后にいろいろなアニメを追加して、ネット上の例は比较的に多くて、简単にみんなにコツを教えます
//
pager.setPageTransformer(true, new ViewPager.PageTransformer() {
@Override
public void transformPage(View page, float position) {
if (position < -1.0f) {
// [-Infinity,-1)
//
} else if (position <= 0.0f) {
// [-1,0]
//
} else if (position <= 1.0f) {
// (0,1]
//
} else {
// (1,+Infinity]
//
}
}
});
これはぜひご理解ください.慕課網千変万化のViewPagerチュートリアルの簡単なプレゼンテーションをお勧めします.
完全demoはgithub SliderLayoutにアップロードされました