android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新
缓存工具类:以url为key,json数据为value,
- package com.itheima.zhbj52.utils;
- import com.itheima.zhbj52.global.GlobalContants;
- import android.content.Context;
- import android.text.TextUtils;
- /**
- * 缓存工具类
- */
- public class CacheUtils {
- /**
- * 设置缓存 key 是url, value是json(服务器返回的数据),图片BitmapUtils已经跟我们做了缓存。
- */
- public static void setCache(String key, String value, Context ctx) {
- PrefUtils.setString(ctx, key, value);
- //可以将缓存放在文件中, 文件名就是Md5(url), 文件内容是json
- }
- // 设置缓存
- //CacheUtils.setCache(GlobalContants.CATEGORIES_URL,result, mActivity);
- //读取缓存
- //String cache = CacheUtils.getCache(GlobalContants.CATEGORIES_URL,mActivity);
- /*
- String cache = CacheUtils.getCache(GlobalContants.CATEGORIES_URL,mActivity);
- if (!TextUtils.isEmpty(cache)) {// 如果缓存存在,直接解析数据, 无需访问网路。后面还是要访问网络,这里使用缓存只是让用户不去急,后面还是会更新的。
- parseData(cache);
- }
- getDataFromServer();// 不管有没有缓存, 都获取最新数据, 保证数据最新
- */
- /**
- * 获取缓存 key 是url
- */
- public static String getCache(String key, Context ctx) {
- return PrefUtils.getString(ctx, key, null);
- }
- }
主页面:
- package com.itheima.zhbj52.base;
- import java.util.ArrayList;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.graphics.Color;
- import android.os.Handler;
- import android.support.v4.view.PagerAdapter;
- import android.support.v4.view.ViewPager;
- import android.support.v4.view.ViewPager.OnPageChangeListener;
- import android.text.TextUtils;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnTouchListener;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.BaseAdapter;
- import android.widget.ImageView;
- import android.widget.ImageView.ScaleType;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.google.gson.Gson;
- import com.itheima.zhbj52.NewsDetailActivity;
- import com.itheima.zhbj52.R;
- import com.itheima.zhbj52.domain.NewsData.NewsTabData;
- import com.itheima.zhbj52.domain.TabData;
- import com.itheima.zhbj52.domain.TabData.TabNewsData;
- import com.itheima.zhbj52.domain.TabData.TopNewsData;
- import com.itheima.zhbj52.global.GlobalContants;
- import com.itheima.zhbj52.utils.CacheUtils;
- import com.itheima.zhbj52.utils.PrefUtils;
- import com.itheima.zhbj52.view.RefreshListView;
- import com.itheima.zhbj52.view.RefreshListView.OnRefreshListener;
- import com.lidroid.xutils.BitmapUtils;
- import com.lidroid.xutils.HttpUtils;
- import com.lidroid.xutils.ViewUtils;
- import com.lidroid.xutils.exception.HttpException;
- import com.lidroid.xutils.http.ResponseInfo;
- import com.lidroid.xutils.http.callback.RequestCallBack;
- import com.lidroid.xutils.http.client.HttpRequest.HttpMethod;
- import com.lidroid.xutils.view.annotation.ViewInject;
- import com.viewpagerindicator.CirclePageIndicator;
- /**
- * 新闻中心-新闻-北京 页签详情页
- */
- public class TabDetailPager extends BaseMenuDetailPager implements OnPageChangeListener {
- NewsTabData mTabData;
- private TextView tvText;
- private String mUrl;
- private TabData mTabDetailData;
- @ViewInject(R.id.vp_news)
- private ViewPager mViewPager;
- @ViewInject(R.id.tv_title)
- private TextView tvTitle;// 头条新闻的标题
- private ArrayList<TopNewsData> mTopNewsList;// 头条新闻数据集合
- @ViewInject(R.id.indicator)
- private CirclePageIndicator mIndicator;// 头条新闻位置指示器(4个黑色的圆点)
- @ViewInject(R.id.lv_list)
- private RefreshListView lvList;// 新闻列表
- private ArrayList<TabNewsData> mNewsList; // 新闻数据集合
- private NewsAdapter mNewsAdapter;
- private String mMoreUrl;// 更多页面的地址
- private Handler mHandler;
- public TabDetailPager(Activity activity, NewsTabData newsTabData) {
- super(activity);
- mTabData = newsTabData;
- mUrl = GlobalContants.SERVER_URL + mTabData.url;
- }
- @Override
- public View initViews() {
- View view = View.inflate(mActivity, R.layout.tab_detail_pager, null);
- /*tab_detail_pager.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <com.itheima.zhbj52.view.RefreshListView
- android:id="@+id/lv_list"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:cacheColorHint="#fff"
- android:layout_weight="1" >
- </com.itheima.zhbj52.view.RefreshListView>
- </LinearLayout>*/
- // 加载头布局
- View headerView = View.inflate(mActivity, R.layout.list_header_topnews,null);
- //list_header_topnews.xml
- /*<?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <com.itheima.zhbj52.view.TopNewsViewPager
- android:id="@+id/vp_news"
- android:layout_width="match_parent"
- android:layout_height="200dp" />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="#a000"
- android:padding="3dp" >
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="#fff"
- android:textSize="16sp" />
- <com.viewpagerindicator.CirclePageIndicator
- android:id="@+id/indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:padding="10dip"
- app:fillColor="#f00"
- app:pageColor="@android:color/darker_gray"
- app:radius="3dp"
- app:strokeWidth="0dp" />
- </RelativeLayout>
- </RelativeLayout>*/
- ViewUtils.inject(this, view);
- ViewUtils.inject(this, headerView);
- // 将头条新闻以头布局的形式加给listview
- lvList.addHeaderView(headerView);
- // 设置下拉刷新监听
- lvList.setOnRefreshListener(new OnRefreshListener() {//自定义监听器
- @Override
- public void onRefresh() {
- getDataFromServer();
- }
- @Override
- public void onLoadMore() {
- if (mMoreUrl != null) {
- getMoreDataFromServer();
- } else {
- Toast.makeText(mActivity, "最后一页了", Toast.LENGTH_SHORT)
- .show();
- lvList.onRefreshComplete(false);// 收起加载更多的布局
- }
- }
- });
- //这里只是方法的调用
- lvList.setOnItemClickListener(new OnItemClickListener() {//执行的是RefreshListView的setOnItemClickListener()方法。
- @Override
- public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
- System.out.println("被点击:" + position);
- // 35311,34221,34234,34342
- // 在本地记录已读状态,将已读新闻的id保存进SharedPreferences(config.xml文件里面),
- String ids = PrefUtils.getString(mActivity, "read_ids", "");
- /*public static String getString(Context ctx, String key, String defaultValue) {
- SharedPreferences sp = ctx.getSharedPreferences("config",
- Context.MODE_PRIVATE);
- return sp.getString(key, defaultValue);
- }*/
- String readId = mNewsList.get(position).id;
- if (!ids.contains(readId)) {//防止重复点击会有重复。
- ids = ids + readId + ",";
- PrefUtils.setString(mActivity, "read_ids", ids);
- /*public static void setString(Context ctx, String key, String value) {
- SharedPreferences sp = ctx.getSharedPreferences(PREF_NAME,
- Context.MODE_PRIVATE);
- sp.edit().putString(key, value).commit();
- }*/
- }
- //mNewsAdapter.notifyDataSetChanged();调用Adapter实现刷新,这里会调用Adapter的getView()方法,这个方法会执行getView()方法很多次。
- changeReadState(view);// 实现局部界面刷新, 这个view就是被点击的item布局对象(点击的某一行),不去刷新所有的listView.
- // 跳转新闻详情页
- Intent intent = new Intent();
- intent.setClass(mActivity, NewsDetailActivity.class);
- intent.putExtra("url", mNewsList.get(position).url);
- mActivity.startActivity(intent);
- }
- });
- return view;
- }
- /**
- * 改变已读新闻的颜色
- */
- private void changeReadState(View view) {
- TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
- tvTitle.setTextColor(Color.GRAY);
- }
- @Override
- public void initData() {
- String cache = CacheUtils.getCache(mUrl, mActivity);//mUrl是key,
- if (!TextUtils.isEmpty(cache)) {
- parseData(cache, false);
- }
- getDataFromServer();
- }
- private void getDataFromServer() {
- HttpUtils utils = new HttpUtils();
- utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
- @Override
- public void onSuccess(ResponseInfo<String> responseInfo) {
- String result = (String) responseInfo.result;
- System.out.println("页签详情页返回结果:" + result);
- parseData(result, false);
- lvList.onRefreshComplete(true);//lvList就是RefreshListView对象
- // 设置缓存
- CacheUtils.setCache(mUrl, result, mActivity);
- }
- @Override
- public void onFailure(HttpException error, String msg) {
- Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
- error.printStackTrace();
- lvList.onRefreshComplete(false);
- }
- });
- }
- /**
- * 加载下一页数据
- */
- private void getMoreDataFromServer() {
- HttpUtils utils = new HttpUtils();
- utils.send(HttpMethod.GET, mMoreUrl, new RequestCallBack<String>() {
- @Override
- public void onSuccess(ResponseInfo<String> responseInfo) {
- String result = (String) responseInfo.result;
- parseData(result, true);
- lvList.onRefreshComplete(true);
- }
- @Override
- public void onFailure(HttpException error, String msg) {
- Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
- error.printStackTrace();
- lvList.onRefreshComplete(false);
- }
- });
- }
- protected void parseData(String result, boolean isMore) {
- Gson gson = new Gson();
- mTabDetailData = gson.fromJson(result, TabData.class);
- System.out.println("页签详情解析:" + mTabDetailData);
- // 处理下一页链接
- String more = mTabDetailData.data.more;
- if (!TextUtils.isEmpty(more)) {
- mMoreUrl = GlobalContants.SERVER_URL + more;
- } else {
- mMoreUrl = null;
- }
- if (!isMore) {
- mTopNewsList = mTabDetailData.data.topnews;
- mNewsList = mTabDetailData.data.news;
- if (mTopNewsList != null) {
- mViewPager.setAdapter(new TopNewsAdapter());
- mIndicator.setViewPager(mViewPager);
- mIndicator.setSnap(true);// 支持快照显示
- mIndicator.setOnPageChangeListener(this);
- mIndicator.onPageSelected(0);// 让指示器重新定位到第一个点
- tvTitle.setText(mTopNewsList.get(0).title);
- }
- if (mNewsList != null) {
- mNewsAdapter = new NewsAdapter();
- lvList.setAdapter(mNewsAdapter);
- }
- // 自动轮播条显示
- if (mHandler == null) {//这里handler只能创建一个,如果创建了多个则多个handler会都发消息来轮播。
- mHandler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- int currentItem = mViewPager.getCurrentItem();
- if (currentItem < mTopNewsList.size() - 1) {
- currentItem++;
- } else {
- currentItem = 0;
- }
- mViewPager.setCurrentItem(currentItem);// 切换到下一个页面
- mHandler.sendEmptyMessageDelayed(0, 3000);// 继续延时3秒发消息,
- // 形成循环
- };
- };
- mHandler.sendEmptyMessageDelayed(0, 3000);// 延时3秒后第一次轮播开始。
- }
- } else {// 如果是加载下一页,需要将数据追加给原来的集合
- ArrayList<TabNewsData> news = mTabDetailData.data.news;
- mNewsList.addAll(news);
- mNewsAdapter.notifyDataSetChanged();
- }
- }
- /**
- * 头条新闻适配器
- */
- class TopNewsAdapter extends PagerAdapter {
- private BitmapUtils utils;
- public TopNewsAdapter() {
- utils = new BitmapUtils(mActivity);
- utils.configDefaultLoadingImage(R.drawable.topnews_item_default);// 设置默认图片
- }
- @Override
- public int getCount() {
- return mTabDetailData.data.topnews.size();
- }
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- return arg0 == arg1;
- }
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- ImageView image = new ImageView(mActivity);
- image.setScaleType(ScaleType.FIT_XY);// 基于控件大小填充图片
- TopNewsData topNewsData = mTopNewsList.get(position);
- utils.display(image, topNewsData.topimage);// 传递imagView对象和图片地址
- container.addView(image);
- image.setOnTouchListener(new TopNewsTouchListener());//设置触摸监听
- return image;
- }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
- }
- }
- /**
- * 头条新闻的触摸监听
- */
- class TopNewsTouchListener implements OnTouchListener {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- System.out.println("按下");
- mHandler.removeCallbacksAndMessages(null);// 删除Handler中的所有消息
- // mHandler.postDelayed(new Runnable() {//mHandler延时去执行某个操作
- // @Override
- // public void run() {}
- // }, 3000);
- break;
- case MotionEvent.ACTION_CANCEL://按下又滑动了,按下和抬起就无效了。
- System.out.println("事件取消");
- mHandler.sendEmptyMessageDelayed(0, 3000);
- break;
- case MotionEvent.ACTION_UP:
- System.out.println("抬起");
- mHandler.sendEmptyMessageDelayed(0, 3000);
- break;
- default:
- break;
- }
- return true;
- }
- }
- /**
- * 新闻列表的适配器
- */
- class NewsAdapter extends BaseAdapter {
- private BitmapUtils utils;
- public NewsAdapter() {
- utils = new BitmapUtils(mActivity);
- utils.configDefaultLoadingImage(R.drawable.pic_item_list_default);//默认图片
- }
- @Override
- public int getCount() {
- return mNewsList.size();
- }
- @Override
- public TabNewsData getItem(int position) {
- return mNewsList.get(position);
- }
- @Override
- public long getItemId(int position) {
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
- if (convertView == null) {
- convertView = View.inflate(mActivity, R.layout.list_news_item,
- null);
- /*<?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="wrap_content"
- android:padding="10dp"
- >
- <ImageView
- android:id="@+id/iv_pic"
- android:layout_width="110dp"
- android:layout_height="70dp"
- android:scaleType="fitXY"
- android:padding="1dp"
- android:background="@android:color/darker_gray"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:src="@drawable/image_demo" />
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="20dp"
- android:layout_toRightOf="@+id/iv_pic"
- android:text="新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题新闻标题"
- android:textColor="#000"
- android:maxLines="2"
- android:ellipsize="end"
- android:textSize="20sp" />
- <TextView
- android:id="@+id/tv_date"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@id/tv_title"
- android:text="2015-03-16 16:20"
- android:layout_alignBottom="@id/iv_pic"
- android:textColor="@android:color/darker_gray"
- android:textSize="16sp" />
- </RelativeLayout>*/
- holder = new ViewHolder();
- holder.ivPic = (ImageView) convertView.findViewById(R.id.iv_pic);
- holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
- holder.tvDate = (TextView) convertView.findViewById(R.id.tv_date);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
- TabNewsData item = getItem(position);
- holder.tvTitle.setText(item.title);
- holder.tvDate.setText(item.pubdate);
- utils.display(holder.ivPic, item.listimage);
- String ids = PrefUtils.getString(mActivity, "read_ids", "");
- if (ids.contains(getItem(position).id)) {//如果是已读则把新闻的文字颜色改为灰色。
- holder.tvTitle.setTextColor(Color.GRAY);
- } else {
- holder.tvTitle.setTextColor(Color.BLACK);
- }
- return convertView;
- }
- }
- static class ViewHolder {
- public TextView tvTitle;
- public TextView tvDate;
- public ImageView ivPic;
- }
- @Override
- public void onPageScrollStateChanged(int arg0) {
- }
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- }
- @Override
- public void onPageSelected(int arg0) {
- TopNewsData topNewsData = mTopNewsList.get(arg0);
- tvTitle.setText(topNewsData.title);
- }
- }
上拉和下拉刷新:
- package com.itheima.zhbj52.view;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.animation.Animation;
- import android.view.animation.RotateAnimation;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.AdapterView;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import com.itheima.zhbj52.R;
- /**
- * 下拉刷新的ListView
- */
- public class RefreshListView extends ListView implements OnScrollListener,
- android.widget.AdapterView.OnItemClickListener {
- //3中状态
- private static final int STATE_PULL_REFRESH = 0;// 下拉刷新
- private static final int STATE_RELEASE_REFRESH = 1;// 松开刷新
- private static final int STATE_REFRESHING = 2;// 正在刷新
- private int mCurrrentState = STATE_PULL_REFRESH;// 当前状态
- private View mHeaderView;
- private int startY = -1;// 滑动起点的y坐标
- private int mHeaderViewHeight;
- private TextView tvTitle;
- private TextView tvTime;
- private ImageView ivArrow;
- private ProgressBar pbProgress;
- private RotateAnimation animUp;
- private RotateAnimation animDown;
- public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initHeaderView();
- initFooterView();
- }
- public RefreshListView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initHeaderView();
- initFooterView();
- }
- public RefreshListView(Context context) {
- super(context);
- initHeaderView();
- initFooterView();
- }
- /**
- * 初始化头布局
- */
- private void initHeaderView() {
- mHeaderView = View.inflate(getContext(), R.layout.refresh_header, null);
- this.addHeaderView(mHeaderView);
- tvTitle = (TextView) mHeaderView.findViewById(R.id.tv_title);
- tvTime = (TextView) mHeaderView.findViewById(R.id.tv_time);
- ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arr);
- pbProgress = (ProgressBar) mHeaderView.findViewById(R.id.pb_progress);
- mHeaderView.measure(0, 0);
- mHeaderViewHeight = mHeaderView.getMeasuredHeight();
- mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏头布局
- initArrowAnim();
- tvTime.setText("最后刷新时间:" + getCurrentTime());
- }
- /*
- * 初始化脚布局
- */
- private void initFooterView() {
- mFooterView = View.inflate(getContext(),R.layout.refresh_listview_footer, null);
- this.addFooterView(mFooterView);
- mFooterView.measure(0, 0);
- mFooterViewHeight = mFooterView.getMeasuredHeight();
- mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);// 隐藏
- this.setOnScrollListener(this);
- }
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- startY = (int) ev.getRawY();
- break;
- case MotionEvent.ACTION_MOVE:
- if (startY == -1) {// 确保startY有效
- startY = (int) ev.getRawY();
- }
- if (mCurrrentState == STATE_REFRESHING) {// 正在刷新时不做处理
- break;
- }
- int endY = (int) ev.getRawY();
- int dy = endY - startY;// 手指移动的便宜量。
- if (dy > 0 && getFirstVisiblePosition() == 0) {// 只有下拉并且当前是第一个item,才允许下拉,已经滑倒列表下面去了,再向下拉刷新是不出来的。
- int padding = dy - mHeaderViewHeight;// 计算padding,padding是下拉刷新的顶部距离屏幕可见部分的距离。
- mHeaderView.setPadding(0, padding, 0, 0);// 设置当前padding
- if (padding > 0 && mCurrrentState != STATE_RELEASE_REFRESH) {// 状态改为松开刷新
- mCurrrentState = STATE_RELEASE_REFRESH;
- refreshState();
- //padding < 0则下拉刷新控件在屏幕里面,padding > 0则下拉刷新控件在屏幕外面。
- } else if (padding < 0 && mCurrrentState != STATE_PULL_REFRESH) {// 改为下拉刷新状态
- mCurrrentState = STATE_PULL_REFRESH;
- refreshState();
- }
- return true;
- }
- break;
- case MotionEvent.ACTION_UP:
- startY = -1;// 重置
- if (mCurrrentState == STATE_RELEASE_REFRESH) {
- mCurrrentState = STATE_REFRESHING;// 正在刷新
- mHeaderView.setPadding(0, 0, 0, 0);// 显示
- refreshState();
- } else if (mCurrrentState == STATE_PULL_REFRESH) {
- mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏
- }
- break;
- default:
- break;
- }
- return super.onTouchEvent(ev);
- }
- /**
- * 刷新下拉控件的布局
- */
- private void refreshState() {
- switch (mCurrrentState) {
- case STATE_PULL_REFRESH:
- tvTitle.setText("下拉刷新");
- ivArrow.setVisibility(View.VISIBLE);
- pbProgress.setVisibility(View.INVISIBLE);
- ivArrow.startAnimation(animDown);
- break;
- case STATE_RELEASE_REFRESH:
- tvTitle.setText("松开刷新");
- ivArrow.setVisibility(View.VISIBLE);
- pbProgress.setVisibility(View.INVISIBLE);
- ivArrow.startAnimation(animUp);
- break;
- case STATE_REFRESHING:
- tvTitle.setText("正在刷新...");
- ivArrow.clearAnimation();// 必须先清除动画,才能隐藏
- ivArrow.setVisibility(View.INVISIBLE);
- pbProgress.setVisibility(View.VISIBLE);
- if (mListener != null) {
- mListener.onRefresh();
- }
- break;
- default:
- break;
- }
- }
- /**
- * 初始化箭头动画
- */
- private void initArrowAnim() {
- // 箭头向上动画
- animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, //0到-180度
- Animation.RELATIVE_TO_SELF, 0.5f);
- animUp.setDuration(200);
- animUp.setFillAfter(true);
- // 箭头向下动画
- animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, //-180到0度
- 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
- animDown.setDuration(200);
- animDown.setFillAfter(true);
- }
- OnRefreshListener mListener;
- private View mFooterView;
- private int mFooterViewHeight;
- public void setOnRefreshListener(OnRefreshListener listener) {
- mListener = listener;
- }
- public interface OnRefreshListener {
- public void onRefresh();
- public void onLoadMore();// 加载下一页数据
- }
- /*
- * 收起下拉刷新的控件
- */
- public void onRefreshComplete(boolean success) {
- if (isLoadingMore) {// 正在加载更多...
- mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);// 隐藏脚布局
- isLoadingMore = false;
- } else {
- mCurrrentState = STATE_PULL_REFRESH;
- tvTitle.setText("下拉刷新");
- ivArrow.setVisibility(View.VISIBLE);
- pbProgress.setVisibility(View.INVISIBLE);
- mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏
- if (success) {
- tvTime.setText("最后刷新时间:" + getCurrentTime());
- }
- }
- }
- /**
- * 获取当前时间
- */
- public String getCurrentTime() {
- //HH为24小时制,hh为12小时制,MM大写一月份从1开始,mm小写一月份从0开始
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- return format.format(new Date());
- }
- private boolean isLoadingMore;
- //ListView的监听器
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- if (scrollState == SCROLL_STATE_IDLE
- || scrollState == SCROLL_STATE_FLING) {
- if (getLastVisiblePosition() == getCount() - 1 && !isLoadingMore) {// 滑动到最后
- System.out.println("到底了.....");
- mFooterView.setPadding(0, 0, 0, 0);// 显示
- setSelection(getCount() - 1);// listview的方法改变listview显示位置。getCount()是listview的方法。
- isLoadingMore = true;//防止多次滑动此方法执行多次。
- if (mListener != null) {
- mListener.onLoadMore();
- }
- }
- }
- }
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- }
- OnItemClickListener mItemClickListener;
- @Override//ListView的方法
- public void setOnItemClickListener(
- android.widget.AdapterView.OnItemClickListener listener) {
- super.setOnItemClickListener(this);//因为传的是this,所以走到下面的onItemClick()方法。
- mItemClickListener = listener;//TabDetailPager传进来的OnItemClickListener
- }
- @Override//响应setOnItemClickListener事件
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- if (mItemClickListener != null) {
- //再去执行TabDetailPager里面的onItemClick()方法
- mItemClickListener.onItemClick(parent, view, position- getHeaderViewsCount(), id);//getHeaderViewsCount()获取头结点的数量,只有减去了头结点的数量才能获取点击的是第几个列表。
- }
- }
- }
刷新头:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal" >
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="10dp" >
- <ImageView
- android:id="@+id/iv_arr"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@drawable/common_listview_headview_red_arrow" />
- <ProgressBar
- android:id="@+id/pb_progress"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminateDrawable="@drawable/custom_progress" 自定义圆环
- <!--
- custom_progress.xml
- <?xml version="1.0" encoding="utf-8"?>
- <rotate xmlns:android="http://schemas.android.com/apk/res/android" 动画
- android:fromDegrees="0"
- android:toDegrees="360" 动画是0度到360度
- android:pivotX="50%" 旋转中心点
- android:pivotY="50%"
- >
- <shape 形状
- android:innerRadius="12dp" 内半径
- android:shape="ring" 圆环
- android:thickness="3dp" 厚度为3dp
- android:useLevel="false" > 去掉默认动画
- <gradient 颜色为渐变
- android:centerColor="#3f00" 起始颜色
- android:endColor="#f00" 终点颜色
- android:startColor="#fff" /> 中间颜色
- </shape>
- </rotate> -->
- android:visibility="invisible" />
- </FrameLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:gravity="center"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="下拉刷新"
- android:textColor="#f00"
- android:textSize="16sp" />
- <TextView
- android:id="@+id/tv_time"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="5dp"
- android:text="最后刷新时间:2015-03-10 17:07:07"
- android:textColor="@android:color/darker_gray"
- android:textSize="14sp" />
- </LinearLayout>
- </LinearLayout>
刷新尾:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:orientation="horizontal" >
- <ProgressBar
- android:id="@+id/pb_pull_list_header"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_margin="5dp"
- android:indeterminateDrawable="@drawable/custom_progress" />
- <!--
- custom_progress.xml
- <?xml version="1.0" encoding="utf-8"?>
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:fromDegrees="0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="360" >
- <shape
- android:innerRadius="12dp"
- android:shape="ring"
- android:thickness="3dp"
- android:useLevel="false" >
- <gradient
- android:centerColor="#3f00"
- android:endColor="#f00"
- android:startColor="#fff" />
- </shape>
- </rotate> -->
- <TextView
- android:id="@+id/tv_pull_list_header_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="加载中..."
- android:textColor="#ff0000"
- android:textSize="18sp" />
- </LinearLayout>
新闻详情页:
- package com.itheima.zhbj52;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.DialogInterface;
- import android.graphics.Bitmap;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.Window;
- import android.webkit.WebChromeClient;
- import android.webkit.WebSettings;
- import android.webkit.WebSettings.TextSize;
- import android.webkit.WebView;
- import android.webkit.WebViewClient;
- import android.widget.ImageButton;
- import android.widget.ProgressBar;
- import cn.sharesdk.framework.ShareSDK;
- import cn.sharesdk.onekeyshare.OnekeyShare;
- import cn.sharesdk.onekeyshare.OnekeyShareTheme;
- /**
- * 新闻详情页
- */
- public class NewsDetailActivity extends Activity implements OnClickListener {
- private WebView mWebView;
- private ImageButton btnBack;
- private ImageButton btnSize;
- private ImageButton btnShare;
- private ProgressBar pbProgress;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_news_detail);
- mWebView = (WebView) findViewById(R.id.wv_web);
- btnBack = (ImageButton) findViewById(R.id.btn_back);
- btnSize = (ImageButton) findViewById(R.id.btn_size);
- btnShare = (ImageButton) findViewById(R.id.btn_share);
- btnBack.setOnClickListener(this);
- btnSize.setOnClickListener(this);
- btnShare.setOnClickListener(this);
- pbProgress = (ProgressBar) findViewById(R.id.pb_progress);
- String url = getIntent().getStringExtra("url");
- //WebView的属性
- WebSettings settings = mWebView.getSettings();
- settings.setJavaScriptEnabled(true);// 表示支持js
- settings.setBuiltInZoomControls(true);// 显示放大缩小按钮
- settings.setUseWideViewPort(true);// 支持双击缩放
- mWebView.setWebViewClient(new WebViewClient() {//回调
- /**
- * 网页开始加载时回调
- */
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- System.out.println("网页开始加载");
- pbProgress.setVisibility(View.VISIBLE);//进度条显示
- }
- /**
- * 网页加载结束时回调
- */
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- System.out.println("网页开始结束");
- pbProgress.setVisibility(View.GONE);//进度条隐藏
- }
- /**
- * 所有点击的跳转的链接都会在此方法中回调
- */
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- // tel:110
- System.out.println("跳转url:" + url);
- view.loadUrl(url);//如果不写这,那么url跳转的时候就是用的网页,这里强制不使用网页使用WebView加载url。
- return true;
- // return super.shouldOverrideUrlLoading(view, url);
- }
- });
- // mWebView.goBack()
- mWebView.setWebChromeClient(new WebChromeClient() {
- /**
- * 网页加载进度发生变化(加载的时候一直调用)
- */
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- System.out.println("加载进度:" + newProgress);
- super.onProgressChanged(view, newProgress);
- }
- /**
- * 获取网页标题
- */
- @Override
- public void onReceivedTitle(WebView view, String title) {
- System.out.println("网页标题:" + title);
- super.onReceivedTitle(view, title);
- }
- });
- mWebView.loadUrl(url);// 加载网页,前面的setWebViewClient和setWebChromeClient不要也可以。
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_back://返回,就是销毁当前页面
- finish();
- break;
- case R.id.btn_size:
- showChooseDialog();//设置字体
- break;
- case R.id.btn_share:
- showShare();//ShareSDK第三方分享平台,集成了其他平台的接口。
- break;
- default:
- break;
- }
- }
- private int mCurrentChooseItem;// 记录当前选中的item, 点击确定前
- private int mCurrentItem = 2;// 记录当前选中的item, 点击确定后
- /**
- * 显示选择对话框
- */
- private void showChooseDialog() {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- String[] items = new String[] { "超大号字体", "大号字体", "正常字体", "小号字体",
- "超小号字体" };
- builder.setTitle("字体设置");
- builder.setSingleChoiceItems(items, mCurrentItem,///mCurrentItem是默认选中的当前字体
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {//这个which是当前选中项,
- System.out.println("选中:" + which);
- mCurrentChooseItem = which;//现在新选择的字体
- }
- });
- builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {//这个which永远是0,
- WebSettings settings = mWebView.getSettings();
- switch (mCurrentChooseItem) {
- case 0:
- settings.setTextSize(TextSize.LARGEST);
- break;
- case 1:
- settings.setTextSize(TextSize.LARGER);
- break;
- case 2:
- settings.setTextSize(TextSize.NORMAL);
- break;
- case 3:
- settings.setTextSize(TextSize.SMALLER);
- break;
- case 4:
- settings.setTextSize(TextSize.SMALLEST);
- break;
- default:
- break;
- }
- mCurrentItem = mCurrentChooseItem;//先前选择的字体
- }
- });
- builder.setNegativeButton("取消", null);//不需要dismiss,系统默认就会dismiss,
- builder.show();
- }
- /**
- * 分享, 注意在sdcard根目录放test.jpg
- */
- private void showShare() {
- ShareSDK.initSDK(this);
- OnekeyShare oks = new OnekeyShare();
- oks.setTheme(OnekeyShareTheme.SKYBLUE);//设置天蓝色的主题
- // 关闭sso授权
- oks.disableSSOWhenAuthorize();
- // 分享时Notification的图标和文字
- oks.setNotification(R.drawable.ic_launcher,
- getString(R.string.app_name));
- // title标题,印象笔记、邮箱、信息、微信、人人网和QQ空间使用
- oks.setTitle(getString(R.string.share));
- // titleUrl是标题的网络链接,仅在人人网和QQ空间使用
- oks.setTitleUrl("http://sharesdk.cn");
- // text是分享文本,所有平台都需要这个字段
- oks.setText("我是分享文本");
- // imagePath是图片的本地路径,Linked-In以外的平台都支持此参数
- oks.setImagePath("/sdcard/test.jpg");// 确保SDcard下面存在此张图片
- // url仅在微信(包括好友和朋友圈)中使用
- oks.setUrl("http://sharesdk.cn");
- // comment是我对这条分享的评论,仅在人人网和QQ空间使用
- oks.setComment("我是测试评论文本");
- // site是分享此内容的网站名称,仅在QQ空间使用
- oks.setSite(getString(R.string.app_name));
- // siteUrl是分享此内容的网站地址,仅在QQ空间使用
- oks.setSiteUrl("http://sharesdk.cn");
- // 启动分享GUI
- oks.show(this);
- }
- }
- activity_news_detail.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/title_red_bg" >
- <ImageButton
- android:id="@+id/btn_back"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginLeft="5dp"
- android:background="@null"
- android:src="@drawable/back" /> 后退按钮
- <ImageButton
- android:id="@+id/btn_share"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="5dp"
- android:background="@null"
- android:src="@drawable/icon_share" /> 分享按钮
- <ImageButton
- android:id="@+id/btn_size"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginRight="5dp"
- android:layout_toLeftOf="@id/btn_share" 在分享按钮左边
- android:background="@null"
- android:src="@drawable/icon_textsize" /> 设置文字大小的按钮
- </RelativeLayout>
- <!-- 帧布局里面的控件可以叠加 -->
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" >
- <!-- WebView用来加载来自网页的数据(跟网页一样的布局) -->
- <WebView
- android:id="@+id/wv_web"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <!-- 网页加载进度的滚动条 -->
- <ProgressBar
- android:id="@+id/pb_progress"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:indeterminateDrawable="@drawable/custom_progress" />
- <?xml version="1.0" encoding="utf-8"?>
- <!-- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:fromDegrees="0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:toDegrees="360" >
- <shape
- android:innerRadius="12dp"
- android:shape="ring"
- android:thickness="3dp"
- android:useLevel="false" >
- <gradient
- android:centerColor="#3f00"
- android:endColor="#f00"
- android:startColor="#fff" />
- </shape>
- </rotate> -->
- </FrameLayout>
- </LinearLayout>
android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新的更多相关文章
- 指令汇B新闻客户端开发(三) 下拉刷新
现在我们继续这个新闻客户端的开发,今天分享的是下拉刷新的实现,我们都知道下拉刷新是一个应用很常见也很实用的功能.我这个应用是通过拉ListView来实现刷新的,先看一张刷新的原理图 从图中可知,手指移 ...
- android新闻项目、饮食助手、下拉刷新、自定义View进度条、ReactNative阅读器等源码
Android精选源码 Android仿照36Kr官方新闻项目课程源码 一个优雅美观的下拉刷新布局,众多样式可选 安卓版本的VegaScroll滚动布局 android物流详情的弹框 健身饮食记录助手 ...
- android123 zhihuibeijing 新闻中心-新闻 页签 ViewPagerIndicator实现
## ViewPagerIndicator ## 使用导入ViewPagerIndicator库的方式相当于可以改源码,打包编译Eclips可以自动完成. ViewPager指针项目,在使用ViewP ...
- 关于mui中一个页面有有多个页签进行切换的下拉刷新加搜索问题
此图是最近做的项目中的一页,用的是mui结合vue,用了mui后,觉得是真心难用啊,先不说其他的,就光这个下拉刷新就让人奔溃了,问题层出不穷,不过最后经过努力还是摆平了哈. 1.每次切换到新的标签,都 ...
- iscroll的下拉刷新,上拉翻页。
首先对iscroll的scrollTo方法进行稍微修改如下图: 对iscroll滑动到屏幕边缘不能弹回的bug进行修复,如下代码: function scrollbug() { var self = ...
- 安卓ListView行详细内容展示页编写和下拉刷新实现
ListView行详细内容展示页: 使用轻量级的Fragment实现Listview行内容简单的详细信息展示: 值得注意的是: 1. 主布局(打开它的Activity)必须是FrameLayout布局 ...
- vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件
vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...
- Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录
经过一个星期的折腾,最终做完了这个Android 聊天表情输入.表情翻页带效果.下拉刷新聊天记录.这仅仅是一个单独聊天表情的输入,以及聊天的效果实现.由于我没有写server,所以没有两方聊天的效果. ...
- 小程序组件-swipe多页切换,并支持下拉刷新,上拉加载,menu动态联动切换
前言 最近一个小程序项目中遇到一个需求,就是实现类似资讯类app的多页面切换的那种效果, 如下图: 最终效果: 1.功能分析 首先实现这个功能分为三步: 实现顶部menu菜单 实现多页面滑动切换 支持 ...
随机推荐
- SCOI2009游戏
1025: [SCOI2009]游戏 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 1065 Solved: 673[Submit][Status] ...
- [swustoj 404] 最小代价树
最小代价树(0404) 问题描述 以下方法称为最小代价的字母树:给定一正整数序列,例如:4,1,2,3,在不改变数的位置的条件下把它们相加,并且用括号来标记每一次加法所得到的和. 例如:((4+1)+ ...
- can't able to update the design capacity in bq27441-G1
/*************************************************************************** * can't able to update ...
- PHPUNIT 单元测试
在windows上的安装可以参考其手册 首先下载phpunit.phar文件 1. 为php的二进制可执行文件建立 一个目录,如C:\bin 2. 将C:\bin添加到系统环境变量中, 3. 打开命令 ...
- service name和SID的区别
数据库名(DB_NAME).实例名(Instance_name).以及操作系统环境变量(ORACLE_SID) 在ORACLE7.8数据库中只有数据库名(db_name)和数据库实例名(instan ...
- 将你的Asp.NET应用程序嵌入到SharePoint
转:http://www.cnblogs.com/Clank/archive/2007/05/21/754073.html 为什么要将Asp.net应用程序嵌入到SharePoint?这个我们不讨论! ...
- 《Python基础教程(第二版)》学习笔记 -> 第四章 字典
字典是Python中唯一内建的映射类型. 字典中的值并没有特殊的顺序,但是都存储在一个特定的键(Key)里.键可以是数字.字符串甚至是元组. 字典的使用 某些情况下,字典比列表更加适用: 表征游戏棋盘 ...
- Mac下安装Mysql出现 Can’t connect to local MySQL server through socket '/tmp/mysql.sock'
在Mac下安装mysql出现 Can't connect to local MySQL server through socket '/tmp/mysql.sock' 错误,解决如下: $ unset ...
- msp时钟设置程序
吐槽一下MSP430需要明白的东西: 在430中,一个时钟周期 = MCLK晶振的倒数.如果MCLK是8M,则一个时钟周期为1/8us: 一个机器周期 = 一个时钟周期,即430每个动作都能完成一个基 ...
- ArcGIS 10.2与CityEngine2013共存的安装
直接上干货 大前提:由于License Manager的不同版本无法同时安装,因此要想ArcGIS和CityEngine共存其License Manger必须一致. 通过校验安装包中License M ...