Android_ViewPager_图片自动翻转

1.设计需求

服务器json数据包含新闻类别,新闻类别可以水平滚动,每个类别下包含多条新闻,新闻图片可以自动翻转~


2.Json数据

{
	"name":"news",
	"count":3,
	"categorylist":[
		{
			"name":"娱乐",
			"count":5,
			"newslist":[
			{
				"title":"赵本山捐款千万办希望小学",
				"imgurl":"ent01.jpg",
				"contenturl":"ent01.html"
			},
			{
				"title":"刘晓庆隐婚1年 拒收老公1千万",
				"imgurl":"ent02.jpg",
				"contenturl":"ent02.html"
			},
			{
				"title":"韩总统朴槿惠变双眼皮疑整容",
				"imgurl":"ent03.jpg",
				"contenturl":"ent03.html"
			},
			{
				"title":"李冰冰任泉否认参与内幕交易",
				"imgurl":"ent04.jpg",
				"contenturl":"ent04.html"
			},
			{
				"title":"明星年收入:吴奇隆吴莫愁过亿",
				"imgurl":"ent05.jpg",
				"contenturl":"ent05.html"
			}
			]
		},
		{
			"name":"体育",
			"count":6,
			"newslist":[
			{
				"title":"首尔FC抵达广州拒绝任何采访",
				"imgurl":"sport01.jpg",
				"contenturl":"sport01.html"
			},
			{
				"title":"乔治21+6步行者擒公牛5连胜",
				"imgurl":"sport02.jpg",
				"contenturl":"sport02.html"
			},
			{
				"title":"专访伊涅斯塔:梅西被批因太强",
				"imgurl":"sport03.jpg",
				"contenturl":"sport03.html"
			},
			{
				"title":"男女篮亚锦赛折戟仍称霸亚洲",
				"imgurl":"sport04.jpg",
				"contenturl":"sport04.html"
			},
			{
				"title":"梅西2球破3场球荒超C罗神迹",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			},
			{
				"title":"双少45分雷霆斩小牛获两连胜",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			}
			]
		},
		{
			"name":"财经",
			"count":5,
			"newslist":[
			{
				"title":"李嘉诚撤资香港或因不满港府",
				"imgurl":"money01.jpg",
				"contenturl":"money01.html"
			},
			{
				"title":"收评:沪指跌0.48%失守120日线",
				"imgurl":"money02.jpg",
				"contenturl":"money02.html"
			},
			{
				"title":"北京:取经英国治霾 应涨油价",
				"imgurl":"money03.jpg",
				"contenturl":"money03.html"
			},
			{
				"title":"韩正澄清为何无北京领导揭牌",
				"imgurl":"money04.jpg",
				"contenturl":"money04.html"
			},
			{
				"title":"北京现代请孙杨代言或被处罚",
				"imgurl":"money05.jpg",
				"contenturl":"money05.html"
			}
			]
		},
		{
			"name":"体育",
			"count":6,
			"newslist":[
			{
				"title":"首尔FC抵达广州拒绝任何采访",
				"imgurl":"sport01.jpg",
				"contenturl":"sport01.html"
			},
			{
				"title":"乔治21+6步行者擒公牛5连胜",
				"imgurl":"sport02.jpg",
				"contenturl":"sport02.html"
			},
			{
				"title":"专访伊涅斯塔:梅西被批因太强",
				"imgurl":"sport03.jpg",
				"contenturl":"sport03.html"
			},
			{
				"title":"男女篮亚锦赛折戟仍称霸亚洲",
				"imgurl":"sport04.jpg",
				"contenturl":"sport04.html"
			},
			{
				"title":"梅西2球破3场球荒超C罗神迹",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			},
			{
				"title":"双少45分雷霆斩小牛获两连胜",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			}
			]
		},
		{
			"name":"财经",
			"count":5,
			"newslist":[
			{
				"title":"李嘉诚撤资香港或因不满港府",
				"imgurl":"money01.jpg",
				"contenturl":"money01.html"
			},
			{
				"title":"收评:沪指跌0.48%失守120日线",
				"imgurl":"money02.jpg",
				"contenturl":"money02.html"
			},
			{
				"title":"北京:取经英国治霾 应涨油价",
				"imgurl":"money03.jpg",
				"contenturl":"money03.html"
			},
			{
				"title":"韩正澄清为何无北京领导揭牌",
				"imgurl":"money04.jpg",
				"contenturl":"money04.html"
			},
			{
				"title":"北京现代请孙杨代言或被处罚",
				"imgurl":"money05.jpg",
				"contenturl":"money05.html"
			}
			]
		},
		{
			"name":"体育",
			"count":6,
			"newslist":[
			{
				"title":"首尔FC抵达广州拒绝任何采访",
				"imgurl":"sport01.jpg",
				"contenturl":"sport01.html"
			},
			{
				"title":"乔治21+6步行者擒公牛5连胜",
				"imgurl":"sport02.jpg",
				"contenturl":"sport02.html"
			},
			{
				"title":"专访伊涅斯塔:梅西被批因太强",
				"imgurl":"sport03.jpg",
				"contenturl":"sport03.html"
			},
			{
				"title":"男女篮亚锦赛折戟仍称霸亚洲",
				"imgurl":"sport04.jpg",
				"contenturl":"sport04.html"
			},
			{
				"title":"梅西2球破3场球荒超C罗神迹",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			},
			{
				"title":"双少45分雷霆斩小牛获两连胜",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			}
			]
		},
		{
			"name":"财经",
			"count":5,
			"newslist":[
			{
				"title":"李嘉诚撤资香港或因不满港府",
				"imgurl":"money01.jpg",
				"contenturl":"money01.html"
			},
			{
				"title":"收评:沪指跌0.48%失守120日线",
				"imgurl":"money02.jpg",
				"contenturl":"money02.html"
			},
			{
				"title":"北京:取经英国治霾 应涨油价",
				"imgurl":"money03.jpg",
				"contenturl":"money03.html"
			},
			{
				"title":"韩正澄清为何无北京领导揭牌",
				"imgurl":"money04.jpg",
				"contenturl":"money04.html"
			},
			{
				"title":"北京现代请孙杨代言或被处罚",
				"imgurl":"money05.jpg",
				"contenturl":"money05.html"
			}
			]
		},
		{
			"name":"体育",
			"count":6,
			"newslist":[
			{
				"title":"首尔FC抵达广州拒绝任何采访",
				"imgurl":"sport01.jpg",
				"contenturl":"sport01.html"
			},
			{
				"title":"乔治21+6步行者擒公牛5连胜",
				"imgurl":"sport02.jpg",
				"contenturl":"sport02.html"
			},
			{
				"title":"专访伊涅斯塔:梅西被批因太强",
				"imgurl":"sport03.jpg",
				"contenturl":"sport03.html"
			},
			{
				"title":"男女篮亚锦赛折戟仍称霸亚洲",
				"imgurl":"sport04.jpg",
				"contenturl":"sport04.html"
			},
			{
				"title":"梅西2球破3场球荒超C罗神迹",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			},
			{
				"title":"双少45分雷霆斩小牛获两连胜",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			}
			]
		},
		{
			"name":"财经",
			"count":5,
			"newslist":[
			{
				"title":"李嘉诚撤资香港或因不满港府",
				"imgurl":"money01.jpg",
				"contenturl":"money01.html"
			},
			{
				"title":"收评:沪指跌0.48%失守120日线",
				"imgurl":"money02.jpg",
				"contenturl":"money02.html"
			},
			{
				"title":"北京:取经英国治霾 应涨油价",
				"imgurl":"money03.jpg",
				"contenturl":"money03.html"
			},
			{
				"title":"韩正澄清为何无北京领导揭牌",
				"imgurl":"money04.jpg",
				"contenturl":"money04.html"
			},
			{
				"title":"北京现代请孙杨代言或被处罚",
				"imgurl":"money05.jpg",
				"contenturl":"money05.html"
			}
			]
		},
		{
			"name":"体育",
			"count":6,
			"newslist":[
			{
				"title":"首尔FC抵达广州拒绝任何采访",
				"imgurl":"sport01.jpg",
				"contenturl":"sport01.html"
			},
			{
				"title":"乔治21+6步行者擒公牛5连胜",
				"imgurl":"sport02.jpg",
				"contenturl":"sport02.html"
			},
			{
				"title":"专访伊涅斯塔:梅西被批因太强",
				"imgurl":"sport03.jpg",
				"contenturl":"sport03.html"
			},
			{
				"title":"男女篮亚锦赛折戟仍称霸亚洲",
				"imgurl":"sport04.jpg",
				"contenturl":"sport04.html"
			},
			{
				"title":"梅西2球破3场球荒超C罗神迹",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			},
			{
				"title":"双少45分雷霆斩小牛获两连胜",
				"imgurl":"sport05.jpg",
				"contenturl":"sport05.html"
			}
			]
		},
		{
			"name":"财经",
			"count":5,
			"newslist":[
			{
				"title":"李嘉诚撤资香港或因不满港府",
				"imgurl":"money01.jpg",
				"contenturl":"money01.html"
			},
			{
				"title":"收评:沪指跌0.48%失守120日线",
				"imgurl":"money02.jpg",
				"contenturl":"money02.html"
			},
			{
				"title":"北京:取经英国治霾 应涨油价",
				"imgurl":"money03.jpg",
				"contenturl":"money03.html"
			},
			{
				"title":"韩正澄清为何无北京领导揭牌",
				"imgurl":"money04.jpg",
				"contenturl":"money04.html"
			},
			{
				"title":"北京现代请孙杨代言或被处罚",
				"imgurl":"money05.jpg",
				"contenturl":"money05.html"
			}
			]
		}
	]
}

3.代码实现

/**
 * 
 * @author http://blog.csdn.net/zimo2013
 *
 */
public class MainActivity extends FragmentActivity implements OnClickListener,
		OnPageChangeListener {
	private RadioGroup rgTitle;
	private TextView tvContent;
	private TextView tvTitle;
	private ScrollView svContent;
	private ViewPager viewPager;
	private ImageGuideAdapter adapter;
	private LinearLayout layoutBottom;
	private LinearLayout[] layouts;

	private NewsInfo newsInfo;
	private int currCategoryIndex;
	private String currContentUrl = "";
	private Category currCategory;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// 请求无标题栏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

		init();

		// 开启任务加载数据
		new JsonTask(handler).start();

		adapter = new ImageGuideAdapter(getSupportFragmentManager(), handler);
		viewPager.setAdapter(adapter);
		viewPager.setOnPageChangeListener(this);
	}

	// 初始化
	private void init() {
		rgTitle = (RadioGroup) findViewById(R.id.rg_title);
		tvContent = (TextView) findViewById(R.id.tv_content);
		tvTitle = (TextView) findViewById(R.id.tv_title);
		viewPager = (ViewPager) findViewById(R.id.pager);
		svContent = (ScrollView) findViewById(R.id.sv_content);
		layoutBottom = (LinearLayout) findViewById(R.id.layoutl_bottom);

		// 得到屏幕的宽度
		int width = getWindowManager().getDefaultDisplay().getWidth();
		ViewGroup.LayoutParams params = viewPager.getLayoutParams();
		params.width = width;
		params.height = width / 2; // 由于viewpager图片等比2:1,故设定viewpager的高度为宽度的1/2
		viewPager.setLayoutParams(params);
	}

	private Handler handler = new Handler() {
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case Constant.STATUS_NET_ERROR:
				showMessage("网络异常!");
				break;

			case Constant.STATUS_JSON_OK:
				String json = new String((byte[]) msg.obj);
				// 解析json
				Gson Gson = new Gson();
				Type type = new TypeToken<NewsInfo>() {
				}.getType();
				newsInfo = Gson.fromJson(json, type);
				// 初始化数据
				initJson();
				break;
			case Constant.STATUS_IMG_OK:
				ImageView iv = (ImageView) msg.obj;
				iv.setImageBitmap((Bitmap) iv.getTag());
				break;
			case Constant.STATUS_CONTENT_OK:
				String result = new String((byte[]) msg.obj);
				if (msg.arg1 == currContentUrl.hashCode()) {// 没有错位
					tvContent.setText(result);
					svContent.scrollTo(0, 0);
				}
				break;
			case Constant.STATUS_NEXT_PAGE:
				viewPager.setCurrentItem(msg.arg1, true);
				break;
			}
		}
	};

	/**
	 * 初始化数据,动态添加radioButton按钮
	 */
	public void initJson() {
		List<Category> categories = newsInfo.getCategorylist();
		ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(100,
				ViewGroup.LayoutParams.MATCH_PARENT);

		for (Category category : categories) {
			RadioButton button = new RadioButton(this);
			button.setText(category.getName());
			button.setGravity(Gravity.CENTER);
			button.setButtonDrawable(R.drawable.boundary_line);
			button.setLayoutParams(params);
			button.setBackgroundResource(R.drawable.selector_title_btn);
			// button.setTextColor(getResources().getColor(R.color.selector_text));
			button.setOnClickListener(this);
			rgTitle.addView(button);
		}

		currCategoryIndex = 0;		//当前类别
		currCategory = categories.get(currCategoryIndex);
		update();
	}

	/**
	 * 更新当前类别新闻的数据
	 * 
	 */
	public void update() {

		layoutBottom.removeAllViews(); // 移除所有子view
		adapter.setList(currCategory.getNewslist());
		adapter.notifyDataSetChanged();

		int size = currCategory.getNewslist().size();
		layouts = new LinearLayout[size];

		//动态添加图片导航提示区域
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		params.leftMargin = 5;
		for (int i = 0; i < size; i++) {
			layouts[i] = new LinearLayout(this);
			layouts[i].setLayoutParams(params);
			System.out.println("layoutBottom:" + layoutBottom);
			layoutBottom.addView(layouts[i]);
		}
		refreshGuide(0);
	}

	/**
	 * 刷新向导进度
	 * 
	 * @param pos
	 */
	public void refreshGuide(int pos) {
		int size = currCategory.getNewslist().size();
		for (int i = 0; i < size; i++) {
			if (i == pos) {
				layouts[i].setBackgroundResource(R.drawable.shape_guide_light);
			} else {
				layouts[i].setBackgroundResource(R.drawable.shape_guide_normal);
			}
		}
		//使用handler,动态延迟刷新下一页
		Message msg = handler.obtainMessage();
		msg.what = Constant.STATUS_NEXT_PAGE;
		if (pos >= size - 1) {
			msg.arg1 = 0;
		} else {
			msg.arg1 = pos + 1;
		}
		handler.sendMessageDelayed(msg, 5 * 1000);
	}

	/**
	 * 输出吐司
	 * 
	 * @param str
	 */
	public void showMessage(String str) {
		Toast.makeText(this, str, 0).show();
	}

	/**
	 * 不同类别新闻button的click事件
	 */
	@Override
	public void onClick(View v) {
		currContentUrl = "";// 当前内容url置空
		tvContent.setText(""); // 详细新闻页置空
		tvTitle.setText("新闻客户端");

		viewPager.setCurrentItem(0);
		currCategoryIndex = rgTitle.indexOfChild(v);
		currCategory = newsInfo.getCategorylist().get(currCategoryIndex);

		update();// 更新当前类别的新闻数据
	}

	@Override
	public void onPageSelected(int position) {
		News news = currCategory.getNewslist().get(position);
		String url = news.getContenturl();
		if (currContentUrl.equals(url)) {
			System.out.println("不重复下载内容!");
			return;
		}
		currContentUrl = url;
		tvTitle.setText(news.getTitle());
		//开启任务,动态下载详细数据
		new ContentTask(handler, currContentUrl).start();
		handler.removeMessages(Constant.STATUS_NEXT_PAGE); //先移除消息,可能还存在延迟尚未处理的消息
		refreshGuide(position);	//重新刷新导航提示,和发送消息
	}

	@Override
	public void onPageScrollStateChanged(int state) {
	}

	@Override
	public void onPageScrolled(int position, float positionOffset,
			int positionOffsetPixels) {
	}
}
/**
 * 
 * @author http://blog.csdn.net/zimo2013
 *
 */
public class ImageGuideAdapter extends FragmentStatePagerAdapter {
	private Handler handler;
	private List<News> lists = new ArrayList<News>();
	private List<ImageGuideFragment> fragments = new ArrayList<ImageGuideFragment>();

	public void setList(List<News> lists) {
		this.lists = lists;
		if(fragments != null){
			fragments.clear();
		}
		for (int i = 0; i < lists.size(); i++) {
			fragments.add(new ImageGuideFragment());
		}
	}

	public ImageGuideAdapter(FragmentManager fm, Handler handler) {
		super(fm);
		this.handler = handler;
	}

	@Override
	public Fragment getItem(int pos) {
		News news = lists.get(pos);
		ImageGuideFragment fragment = fragments.get(pos);
		
		Bundle bundle = new Bundle();
		bundle.putString("title", news.getTitle());
		bundle.putString("imgurl", news.getImgurl());
		fragment.setArguments(bundle);
		//为fragment设置handler,如果缓存中不存在该图片,可以开启网络下载,当下载完成之后,利用handler可以再加载图片资源
		fragment.setHandler(handler);	
		return fragment;
	}

	@Override
	public int getCount() {
		return lists.size();
	}
}
/**
 * 
 * @author http://blog.csdn.net/zimo2013
 *
 */
public class ImageGuideFragment extends Fragment{
	private Handler handler;
	private String title;
	private String imgurl;
	
	public void setHandler(Handler handler){
		this.handler = handler;
	}
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bundle bundle = getArguments();
		title = bundle.getString("title");
		imgurl = bundle.getString("imgurl");
	}
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.item_image, null);
		ImageView ivImg = (ImageView) view.findViewById(R.id.item_iv_img);
		TextView tvTitle = (TextView) view.findViewById(R.id.item_tv_title);
		tvTitle.setText(title);
		if(!TextUtils.isEmpty(imgurl)){	//存在图片url链接
			Bitmap bitmap = AppCacheManager.getManager().getCacheBitmapByKey(imgurl);
			if(bitmap != null){	//缓存中存在图片资源
				System.out.println(imgurl+"图片发现!");
				ivImg.setImageBitmap(bitmap);
			}else{
				//开启多线程,下载图片
				new ImageTask(handler, ivImg, imgurl).start();
			}
		}
		return view;
	}
}
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/bg"
        android:gravity="center"
        android:text="新闻客户端"
        android:textColor="#ffffffff"
        android:textSize="22sp" />

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffe7e7e7"
        android:scrollbarThumbHorizontal="@drawable/bar" >

        <RadioGroup
            android:id="@+id/rg_title"
            android:layout_width="wrap_content"
            android:layout_height="45dp"
            android:orientation="horizontal" >
        </RadioGroup>
    </HorizontalScrollView>

    <View
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:background="@color/bg" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="100dp" >
        </android.support.v4.view.ViewPager>

        <LinearLayout
            android:id="@+id/layoutl_bottom"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            android:layout_alignBottom="@+id/pager"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:gravity="center_vertical"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

    <View
        android:layout_width="fill_parent"
        android:layout_height="2dp"
        android:background="@color/bg" />

    <ScrollView
        android:id="@+id/sv_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/list_bg" >

        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp" />
    </ScrollView>

</LinearLayout>
<!-- item_image.xml -->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="2dp"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/item_iv_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        android:src="@drawable/pic_no" />

    <TextView
        android:id="@+id/item_tv_title"
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:background="#77181410"
        android:gravity="left"
        android:maxLines="1"
        android:paddingLeft="10dp"
        android:textColor="@android:color/white"
        android:textSize="15sp" />

</RelativeLayout>

这里只粘贴关键代码,实体类和三级缓存就没有粘贴在这里,有兴趣的朋友,可以关注我后期关于三级缓存的实现,此处我只是抛砖引玉,希望大家能够指正或者提出更好的实现,


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值