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>

 

 
posted @ 2015-12-20 14:51  无天666  阅读(369)  评论(0编辑  收藏  举报