简介
一个通用的图片轮播效果的通用组件,方便开发者快速集成。
初学者,其实应该实现一个自定义控件的,改天有空,在学习下吧,学习能力一般,以前也没写过java,这个组件都写了好久,惭愧啊。
背景
笔者参考http://blog.csdn.net/allen315410/article/details/39294343 学习了图片轮播效果的实现。在浏览代码的过程中,总觉得图片轮播的效果和Android Activity的耦合过高,如果一个开发者要集成该功能,会将整个功能代码和自己的App代码搅在一起,提高代码的复杂度。同时图片和图片文字描述存放在两个独立的ArrayList,这样的对应关系要由开发者手动维护,时刻关注对应关系正确性。
为什么需要组件:组件开发的目的,即让开发者用最少的代码,调用最少的接口,实现开发者的需求。
以上的描述是笔者对组件概念的最基本的认识,也是基于该原则,笔者基于http://blog.csdn.net/allen315410/article/details/39294343 进行了重构,实现了一个相对内聚的组件。
图片轮播的要素
如果一个开发者需要开发一个图片轮播的功能,开发者最少需要提供的元素有哪些:
- 轮播的图片元素
- 每个图片对应的文字描述
- 轮播图片在布局中的位置
- 图片描述在布局中的位置
- 图片轮播的时间间隔
理论上讲,开发者只需要提高以上几个元素即可,剩下的就有组件完成吧。基于以上思路,开发者大概只需要完成类似代码即可:
public class MainActivity extends Activity {
//提供一个ViewPagerItem类型数组,ViewPagerItem包括了图片信息和图片对应描述信息,采用一一对应的方式,方便维护
private ViewPagerItem[] viewPagerItem = new ViewPagerItem[] {
new ViewPagerItem(R.drawable.a, "0图片描述信息0"),
new ViewPagerItem(R.drawable.b, "1图片描述信息1"),
new ViewPagerItem(R.drawable.c, "2图片描述信息2"),
new ViewPagerItem(R.drawable.d, "3图片描述信息3"),
new ViewPagerItem(R.drawable.e, "4图片描述信息4"),
new ViewPagerItem(R.drawable.e, "5图片描述信息5"),
};
private ViewPagerShow mViewPagerShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//提供一个layout布局容器,用来指定图片展示的位置
LinearLayout container = (LinearLayout) findViewById(R.id.dot_container);
//new一个ViewPagerShow,提供相应参数
mViewPagerShow = new ViewPagerShow(viewPagerItem, this, (ViewPager)findViewById(R.id.vp), mHandler,
(TextView)findViewById(R.id.title), container);
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
/**
* 接收子线程传递过来的数据,调用ViewPagerShow提供的update方法,实现ui的更新
*/
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
mViewPagerShow.update();
};
};
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
}
浏览以上代码,不难发现该功能的加入,对开发者原有的代码的侵入范围不是很大。
用尽量少的代码,完成功能需求,是软件开发人员不断的追求。
轮播组件的实现
下面附上图片轮播效果组件的代码实现:
package com.example.image.view;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static android.content.ContentValues.TAG;
/**
* Created by image on 2017/7/14.
*/
class ViewPagerItem {
public int iMageId;
public String iMageTitle;
public ViewPagerItem(int iMageId, String iMageTitle) {
this.iMageId = iMageId;
this.iMageTitle = iMageTitle;
}
}
class ViewPagerAdapter extends PagerAdapter {
private List<ImageView> iMageViews;
public ViewPagerAdapter(List<ImageView> iMageViews) {
this.iMageViews = iMageViews;
}
@Override
public int getCount() {
return iMageViews.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup view, int position, Object object) {
// TODO Auto-generated method stub
view.removeView(iMageViews.get(position));
}
@Override
public Object instantiateItem(ViewGroup view, int position) {
// TODO Auto-generated method stub
view.addView(iMageViews.get(position));
return iMageViews.get(position);
}
}
class cloneView extends View {
public cloneView(Context context) {
super(context);
}
public cloneView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public cloneView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public cloneView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public Object clone(){
Object o=null;
try {
o=super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
class ViewPagerShow {
private ArrayList<View> dots;
private ViewPagerItem[] viewPagerItem;
private List<ImageView> iMagesList;
private Context context;
private ViewPagerAdapter mViewPagerAdapter;
private ViewPager mViewPager;
private ScheduledExecutorService scheduledExecutorService;
private Handler mHandler;
private int currentItem = 0;
private TextView titleText;
private LinearLayout container;
private View dot_focus, dot_unfocus;
private class ViewPageTask implements Runnable{
@Override
public void run() {
currentItem = (currentItem + 1) % viewPagerItem.length;
mHandler.sendEmptyMessage(0);
};
}
public void dotUpdate() {
container.removeAllViews();
View view;
for (int i = 0; i < this.viewPagerItem.length; i++) {
if (i == currentItem) {
view = LayoutInflater.from(context).inflate(R.layout.dot_focus, null);
container.addView(view);
} else {
view = LayoutInflater.from(context).inflate(R.layout.dot_unfocus, null);
container.addView(view);
}
}
}
public ViewPagerShow(final ViewPagerItem[] viewPagerItem, Context context, ViewPager mViewPager, Handler mHandler,
final TextView titleText, LinearLayout container) {
this.viewPagerItem = viewPagerItem;
this.context = context;
this.mViewPager = mViewPager;
this.mHandler = mHandler;
this.titleText = titleText;
this.container = container;
this.dot_focus = dot_focus;
this.dot_unfocus = dot_unfocus;
/* show first pic title */
titleText.setText(viewPagerItem[0].iMageTitle);
iMagesList = new ArrayList<ImageView>();
for (int i = 0; i < this.viewPagerItem.length; i++) {
ImageView imageView = new ImageView(context);
imageView.setBackgroundResource(viewPagerItem[i].iMageId);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d(TAG, "onClick: onClick");;
}
});
iMagesList.add(imageView);
}
dotUpdate();
mViewPagerAdapter = new ViewPagerAdapter(iMagesList);
mViewPager.setAdapter(mViewPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
titleText.setText(viewPagerItem[position].iMageTitle);
currentItem = position;
dotUpdate();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleWithFixedDelay(new ViewPageTask(), 5, 5, TimeUnit.SECONDS);
}
public void update() {
mViewPager.setCurrentItem(currentItem);
titleText.setText(viewPagerItem[currentItem].iMageTitle);
dotUpdate();
}
}
图片轮播的原理,基本都是参考http://blog.csdn.net/allen315410/article/details/39294343 该篇blog的介绍,这里做的主要的事情即把相关的接口进行一个整理,集中,剥离出一个通用的处理组件,方便开发者的集成。
目前该组件的实现还比较粗糙,待后续持续的更新,完善
文章写的很随意,时间精力关系很多细节没有讲到,最后附上github地址,供参考:https://github.com/imagec/ViewPager