实现:ViewFlipper的网络图片动态加载;自动切换图片时导航按钮相应切换;手动切换图片时导航按钮相应切换;手动切换导航按钮时图片相应切换。
效果图:
1、xml布局代码
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ViewFlipper
android:id="@+id/vf_home_banner"
android:layout_width="match_parent"
android:layout_height="230dp"
android:autoStart="true"
android:flipInterval="5000">
</ViewFlipper>
<RadioGroup
android:id="@+id/rg_picture_chooser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="210dp"
android:orientation="horizontal">
</RadioGroup>
</RelativeLayout>
2、java代码
2.1 动态设置好ViewFlipper内的材料
2.1.1 需要的变量
/**
* 网络图片的地址集合
*/
private List<String> mImageUrl = new ArrayList<>();
/**
* 图片的集合
*/
private List<Bitmap> mImages = new ArrayList<>();
/**
* 已下载图片的计数
*/
private int mImageCount = 0;
2.1.2 下载图片到本地
//假设拿到网络图片的路径
this.mImageUrl.add("http://192.168.1.250:8080/pictures/brucelee1.jpg");
this.mImageUrl.add("http://192.168.1.250:8080/pictures/brucelee2.jpg");
this.mImageUrl.add("http://192.168.1.250:8080/pictures/brucelee3.jpg");
//遍历每一个路径,发送网络请求,下载到本地
Iterator<String> iterator = mImageUrl.iterator();
while (iterator.hasNext()) {
String url = iterator.next();
//自己封装的下载图片到本地的方法
ImageUtility.downloadFileToLocal(url, WriteToFileUtility.getCacheDirPath() + "/" + getImageName(url), mHandler);
}
//每一个图片下载完成后的处理
case ImageUtility.MSG_WHAT_REQUEST_DOWNLOAD_IMAGE:
//将刚下载的那张图片放到bitmap的集合里
Bitmap bitmap = BitmapFactory.decodeFile((String) msg.obj);
fragment.mImages.add(bitmap);
//每下载完成一张图片将已下载图片的计数+1
fragment.mImageCount++;
//当将所有路径的图片都下载完成后,将这些图片统一加入ViewFlipper
if (fragment.mImageCount == fragment.mImageUrl.size()) {
fragment.fillViewFlipper();
}
break;
2.1.3 图片下载完成后,将图片放入ViewFlipper
private void fillViewFlipper() {
Iterator<Bitmap> iterator = mImages.iterator();
while (iterator.hasNext()) {
Bitmap bitmap = iterator.next();
//新建图片
ImageView iv = new ImageView(mContext);
iv.setImageBitmap(bitmap);
//让图片适应viewflipper的大小
iv.setScaleType(ImageView.ScaleType.FIT_XY);
//将图片加入ViewFlipper
mVfBanner.addView(iv);
}
}
2.2 动态设置好RadioButton里的材料
/**
* 选择图片的radiogroup
*/
private RadioGroup mRgPictureChooser = null;
//设置radiobutton的属性
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.width = DensityUtil.dip2px(20);
params.height = DensityUtil.dip2px(20);
//有几个图片地址就动态生成几个radiobutton
for (int i = 0; i < mImageUrl.size(); i++) {
RadioButton radioButton = new RadioButton(mContext);
radioButton.setButtonDrawable(R.drawable.selector_radio_button_home);
//将新建的radiobutton加入到radiogroup
mRgPictureChooser.addView(radioButton, params);
}
2.3 实现ViewFlipper的手动翻页
//设置flipperview的触摸监听
mVfBanner.setOnTouchListener(this);
类要实现OnTouchListener接口
public class HomeFragment implements View.OnTouchListener {
重写触摸回调
@Override
public boolean onTouch(View v, MotionEvent event) {
return mDetector.onTouchEvent(event);
}
需要的变量
/**
* 手势检测
*/
private GestureDetector mDetector = null;
初始化变量
this.mDetector = new GestureDetector(mContext, new SimpleGestureListener());
手动翻页的实现
/**
* 实现左右滑动切换到相应的图片
*/
private class SimpleGestureListener extends GestureDetector.SimpleOnGestureListener {
final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;
//不知道为什么,不加上onDown函数的话,onFling就不会响应,真是奇怪
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// Fling left
if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
//当向左滑动时,显示下一张图片
mVfBanner.showNext();
} else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
// Fling right
mVfBanner.setOutAnimation(mContext, R.anim.slide_right_out);
mVfBanner.setInAnimation(mContext, R.anim.slide_left_in);
//当向右滑动时,显示上一张图片
mVfBanner.showPrevious();
focusRadioButton();
mVfBanner.setOutAnimation(mContext, R.anim.slide_left_out);
mVfBanner.setInAnimation(mContext, R.anim.slide_right_in);
Animation.AnimationListener animationListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
focusRadioButton();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
};
mVfBanner.getInAnimation().setAnimationListener(animationListener);
}
return true;
}
}
2.4 ViewFlipper和RadioGroup的联动
2.4.1 图片切换时,相应的radiobutton点亮
//给ViewFlipper设置切换动画,通过对这个切换动画的监听间接实现对ViewFlipper切换图片的监听(注:因为ViewFlipper本身是没有切换图片的回调的,所有只有这样实现)
mVfBanner.setOutAnimation(mContext, R.anim.slide_left_out);
mVfBanner.setInAnimation(mContext, R.anim.slide_right_in);
Animation.AnimationListener animationListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
focusRadioButton();
}
@Override
public void onAnimationRepeat(Animation animation) {
}
};
mVfBanner.getInAnimation().setAnimationListener(animationListener);
/**
* 根据正在展示的图片,点亮相应的radiobutton
*/
private void focusRadioButton() {
//拿取ViewFlipper正在展示的图片
int flag = mVfBanner.getDisplayedChild();
//得到相对应的应该点亮的RadioButton
RadioButton radioButton = (RadioButton) mRgPictureChooser.getChildAt(flag);
//点亮RadioButton
radioButton.setChecked(true);
}
2.4.2 选中RadioButton,ViewFlipper切换到相应的图片
//遍历每一个RadioButton,设置点击事件
for (int i = 0; i < mImageUrl.size(); i++) {
RadioButton radioButton = (RadioButton) mRgPictureChooser.getChildAt(i);
final int finalI = i;
radioButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击的是第几个按钮,就切换到第几个图片
mVfBanner.setDisplayedChild(finalI);
}
});
}