Android仿人人客户端(v5.7.1)——个人主页(一)

转载请标明出处:http://blog.csdn.net/android_ls/article/details/9248013
声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。
      这篇是在前面的系列文章的基础上展开的,不明白的可以先翻看下前面的文章。

一、实现个人主页顶部导航栏

        1、自定义类(PersonalHomepageActivity)去继承NetworkBaseActivity,源码如下:

package com.everyone.android.ui;

import android.os.Bundle;

import com.everyone.android.api.NetworkBaseActivity;

/**
 * 功能描述:个人主页(当前登录用户的个人主页或者好友的个人主页)
 * @author android_ls
 */
public class PersonalHomepageActivity extends NetworkBaseActivity {

    /**
     * LOG打印标签
     */
    private static final String TAG = PersonalHomepageActivity.class.getSimpleName();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    protected int getLayoutId() {
        return 0;
    }

    @Override
    protected void setupViews() {
        // TODO Auto-generated method stub

    }

    @Override
    protected void initialized() {
        // TODO Auto-generated method stub
    }
    
}
  2、设置布局文件,修改自定义顶部导航栏的外观。

     a.设置布局文件,源码如下:

    @Override
    protected int getLayoutId() {
        return R.layout.personal_homepage;
    }
             b. 布局文件(personal_homepage.xml)里的配置如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <com.everyone.android.widget.TopMenuNavbar
        android:id="@+id/rl_top_menu_navbar"
        style="@style/top_navbar" />

</LinearLayout>
            c. 修改自定义顶部导航栏的外观,源码如下:

    @Override
    protected void setupViews() {
        topMenuNavbar = (TopMenuNavbar) this.findViewById(R.id.rl_top_menu_navbar);
        topMenuNavbar.tvRightOperationName.setVisibility(View.GONE);
        topMenuNavbar.ivRightLine.setVisibility(View.GONE);

        // 将顶部左侧的menu图标换成back图标
        LinearLayout llBackMenu = topMenuNavbar.llShowMenu;
        ImageView ivBack = (ImageView) llBackMenu.findViewById(R.id.iv_back);
        ivBack.setImageResource(R.drawable.v5_0_1_flipper_head_back);

        // 将顶部右侧的刷新按钮换成下拉菜单图标
        LinearLayout llDownOperation = topMenuNavbar.mLlRefresh;
        ImageView ivOperation = (ImageView) llDownOperation.findViewById(R.id.iv_refresh);
        ivOperation.setImageResource(R.drawable.v5_0_1_flipper_head_menu);
        
    }
            d.运行后效果图如下:



二、实现个人主页Header部分

   1、布局文件(personal_homepage.xml)中添加XListView组件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <com.everyone.android.widget.TopMenuNavbar
        android:id="@+id/rl_top_menu_navbar"
        style="@style/top_navbar" />

   <com.everyone.android.widget.XListView
        android:id="@+id/listview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#00000000"
        android:cacheColorHint="#00000000"
        android:divider="@drawable/v5_0_1_newsfeed_divider"
        android:listSelector="@null" 
        android:fastScrollEnabled="true"
       />

</LinearLayout>
   2、在 setupViews() 方法中添加获取XListView组件,为其设置数据适配器(与新鲜事界面的列表使用同一适配器),并添加HeadView的处理。

        mListView = (XListView) this.findViewById(R.id.listview);
        mListView.setPullLoadEnable(false);
        mListView.setPullRefreshEnable(false);
        mListView.setXListViewListener(this);

        mInflater = LayoutInflater.from(this.getContext());
        LinearLayout mHeadView = (LinearLayout) mInflater.inflate(R.layout.personal_homepage_head, null);
        mListView.addHeaderView(mHeadView);

        mFreshNewsAdapter = new FreshNewsAdapter(this, mFreshNewsList);
        mListView.setAdapter(mFreshNewsAdapter);
   3、 HeadView的布局文件(personal_homepage_head.xml)源码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FFFFFF"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/v5_0_1_profile_header_background"
        android:padding="10dip" >
        <ImageView
            android:id="@+id/iv_icon"
            android:layout_width="120dip"
            android:layout_height="120dip"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:background="@drawable/v5_0_1_profile_headphoto"
            android:scaleType="centerCrop" />

        <ImageView
            android:id="@+id/iv_icon_update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@+id/iv_icon"
            android:layout_alignRight="@+id/iv_icon"
            android:src="@drawable/v5_0_1_profile_headphoto_update_icon"
            android:visibility="gone" />

        <LinearLayout
            android:id="@+id/ll_basic_info"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_toRightOf="@+id/iv_icon"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/tv_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FF333333"
                android:textSize="16sp" />

            <ImageView
                android:id="@+id/iv_star"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dip"
                android:src="@drawable/v5_0_1_icon_profile_star"
                android:visibility="gone" />
            
             <Button
                    android:id="@+id/btn_vip"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/v5_0_1_newsfeed_vip_gray_bg"
                    android:text="VIP1"
                    android:textColor="#FFFFFF" 
                    android:visibility="gone"/>
        </LinearLayout>

        <TextView
            android:id="@+id/tv_status_content"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/ll_basic_info"
            android:layout_marginLeft="10dip"
            android:layout_toRightOf="@+id/iv_icon"
            android:textColor="#ff888888"
            android:textSize="14sp" />
    </RelativeLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/tv_type"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dip"
            android:layout_marginLeft="15dip"
            android:layout_marginTop="8dip"
            android:text="新鲜事"
            android:textColor="#FF333333"
            android:textSize="13sp" />

        <TextView
            android:id="@+id/tv_type_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#FF333333"
            android:textSize="13sp" />
    </LinearLayout>

    <View
        android:layout_width="fill_parent"
        android:layout_height="1.5dip"
        android:background="@drawable/v5_0_1_profile_header_divider" />

</LinearLayout>
   4、获取 HeadView的子组件,并为其从服务器端获取数据显示到相应的组件。

    a.获取HeadView的子组件,源码如下:

        tvName = (TextView) mHeadView.findViewById(R.id.tv_name);
        ivIconView = (ImageView) mHeadView.findViewById(R.id.iv_icon);
        ivStar = (ImageView) mHeadView.findViewById(R.id.iv_star);
        tvStatusContent = (TextView) mHeadView.findViewById(R.id.tv_status_content);
        btnVip = (Button) mHeadView.findViewById(R.id.btn_vip);
          b.从网络获取数据并解析,显示到相应的组件,源码如下:

/**
     * 获取用户个人主页的信息
     */
    public void getProfileInfo() {
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);

        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML
        parameter.put("call_id", "1.0"); // 请求队列号

        parameter.put("method", "users.getProfileInfo");
        parameter.put("uid", uid + ""); // 个人主页用户的Id 
        parameter.put("fields", "base_info,status"); // 需要获取的信息的字段列表,各个字段用逗号隔开。
        AsyncHttpsPost asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public Object parse(String json) throws JSONException {
                LogUtil.i(TAG, "json = " + json);
                final JSONObject jsonObject = new JSONObject(json);
                
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        String name = jsonObject.optString("name");
                        LogUtil.i(TAG, "name = " + name);
                        
                        String headurl = jsonObject.optString("headurl");
                        LogUtil.i(TAG, "headurl = " + headurl);

                        int star = jsonObject.optInt("star");
                        LogUtil.i(TAG, "star = " + star);
                      
                        JSONObject jsonStatus = jsonObject.optJSONObject("status");
                        String status = jsonStatus.optString("content");
                        LogUtil.i(TAG, "status = " + status);
                        
                        tvName.setText(name);
                        tvStatusContent.setText(status);
                        
                        if (star == 1) {
                            ivStar.setVisibility(View.VISIBLE);
                        }

                        // 加载用户图像
                        ImageInfo imgInfo = new ImageInfo(ivIconView, headurl);
                        new ImageLoader(PersonalHomepageActivity.this).displayImage(imgInfo);
                        
                    }
                });

                return null;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(final Object obj) {

            }

            @Override
            public void onFail(int errorCode) {
                LogUtil.i(TAG, "freshNewsList errorCode = " + errorCode);

            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }
          c.网络请求返回的JSON字符串如下:
             {
                    "uid":221659942,
                    "status":{"content":"我才知道草莓翻转,是这个意思(偷笑) 转自谭静:明天最后一门考试,结束后,就真的迎来暑假啦~~哇卡卡卡~~~下学期也终于木有课了~~~(twg)(大笑)(ys)(流口水)","time":"2013-07-02 14:37:01"},
                    "star":1,
                    "network_name":"西北大学",
                    "headurl":"http://hdn.xnimg.cn/photos/hdn421/20130614/1350/tiny_cm9Q_ec73000461fa113e.jpg",
                    "name":"谭静",
                    "base_info":{"birth":{"birth_month":3,"birth_day":21,"birth_year":"1987"},"hometown":{"province":"河北","city":"唐山市"},"gender":0}
                 }
      大家仔细看人人服务器端返回的JSON字符串里,会发现没有我们想要的判断当前用户是否为vip用户,vip等级的字段。

        d.我们运行下看看效果怎么样,效果图如下:


   我们看到的用户图像好模糊哦,可是人人官方的应用运行后的效果很好啊,他们怎么实现的呢?我继续翻看人人官方提供的API,发现有users.getInfo这么个接口,编写程序调用这个接口,代码如下:

    /**
     * 获取用户的图像
     * @param uid 用户Id
     */
    public void getUserImage(){
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);
        
        // 获取用户信息所需的参数
        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML,推荐使用JSON,缺省值为XML 
        parameter.put("call_id", "1.0"); // 请求队列号 
        
        parameter.put("method", "users.getInfo"); // 你要访问那个接口,我们肯定调用用获取用户的信息的接口咯,该接口支持批量获取。
        parameter.put("uids", uid + ""); // 个人主页用户的Id 
        parameter.put("fields", "zidou,vip,mainurl"); // 返回的字段列表,可以指定返回那些字段,用逗号分隔。
        
        AsyncBaseRequest asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public Object parse(String json) throws JSONException {
                LogUtil.i(TAG, "---------->json = " + json);

                JSONArray jsonArray = new JSONArray(json);
                JSONObject jsonObject = jsonArray.getJSONObject(0);
                int vip = jsonObject.optInt("vip");
                LogUtil.i(TAG, "vip = " + vip);

                int zidou = jsonObject.optInt("zidou");
                LogUtil.i(TAG, "zidou = " + zidou);
                
                String headurl = jsonObject.optString("mainurl");
                LogUtil.i(TAG, "headurl = " + headurl);
               
                if (TextUtils.isEmpty(headurl)) {
                    LogUtil.i(TAG, "用户图像对应的URL为null");
                    return null;
                }
                
                final String imageUrl = headurl;
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        ImageInfo imgInfo = new ImageInfo(ivIconView, imageUrl);
                        new ImageLoader(PersonalHomepageActivity.this).displayImage(imgInfo);   
                    }
                });
                
                return null;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(Object obj) {
                
            }

            @Override
            public void onFail(int errorCode) {
                // TODO Auto-generated method stub
            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }
     请求服务器端,返回的JSON字符串如下:

 [
    {
        "uid":221659942,
        "vip":1,
        "mainurl":"http://hdn.xnimg.cn/photos/hdn221/20130614/1350/h_main_hIfE_e8e9000001ad113e.jpg",
        "zidou":0
     }
   ]
    运行后的效果图如下:



   感觉是不是好了很多,我们既然已实现想要的效果,那就多从新鲜事列表的Item中点击用户图像,来回切切看,发现有问题了,有一张图片没显示出来,如下图:


什么原因呢?查看服务器端返回的JSON字符串如下:

 [
     {
         "uid":600038849,
         "tinyurl":"http://hdn.xnimg.cn/photos/hdn221/20110212/1700/h_tiny_2ZyG_4a320001f9f62f75.jpg",
         "vip":1,
         "sex":1,
         "name":"折翼の天使",
         "star":1,
         "headurl":"http://hdn.xnimg.cn/photos/hdn221/20110212/1700/h_head_jMyd_4a320001f9f62f75.jpg",
         "zidou":0
      }
    ]
            我有些困惑,同一个接口相同的调用方式,两次所请求字段列表一样,返回的JSON字符串的字段既然不一样。我个人估计这个可能是人人服务器端的一个BUG,他们到目前也还未发现,或者发现了还未来的急修复。

    注:获取个人主页数据,人人官方提供的接口,我觉得有待改进。最起码你不能让我为了两个字段再去请求次服务器吧。(大图像和VIP相关的字段)

三、个人主页的新鲜事的实现(基本上和前面的新鲜事界面的实现是一样的)    

    1、从网络请求有关当前好友的新鲜事数据,代码如下:

 /**
     * 向服务器端请求新鲜事的数据
     */
    public void getFreshNews() {
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);

        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML
        parameter.put("call_id", "1.0"); // 请求队列号
        parameter.put("method", "feed.get");
        parameter.put("type", fresh_news_type); // 新鲜事的类别,多个类型以逗号分隔,type列表 
        parameter.put("uid", uid + ""); // 支持传入当前用户的一个好友ID,表示获取此好友的新鲜事,如果不传,默认为获取当前用户的新鲜事 
        parameter.put("page", page + ""); // 支持分页,指定页号,页号从1开始,默认值为1 
        parameter.put("count", pageCount + ""); // 支持分页,每一页记录数,默认值为30,最大50 
        AsyncHttpsPost asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public LinkedList<FreshNews> parse(String json) throws JSONException {
                LogUtil.i(TAG, "json = " + json);
                if ("[]".equals(json)) {
                    return null;
                }

                Gson gson = new Gson();
                java.lang.reflect.Type type = new TypeToken<LinkedList<FreshNews>>() {
                }.getType();
                LinkedList<FreshNews> freshNewsList = gson.fromJson(json, type);

                LogUtil.e(TAG, "freshNewsList = " + freshNewsList.size());
                return freshNewsList;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(final Object obj) {
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {

                        if (obj != null && obj instanceof LinkedList) {
                            @SuppressWarnings("unchecked")
                            LinkedList<FreshNews> freshNewsList = (LinkedList<FreshNews>) obj;
                            if (freshNewsList.size() > 0) {
                                // 下拉刷新的数据去重复处理
                                if (page == 1 && mFreshNewsList.size() > 0) {
                                    for (FreshNews freshNews : freshNewsList) {
                                        boolean flage = false;
                                        for (FreshNews fresh : mFreshNewsList) {
                                            if(freshNews.getPost_id() == fresh.getPost_id()){
                                                flage = true;
                                            }
                                        }
                                        
                                        if(flage == false){
                                            mFreshNewsList.addFirst(freshNews);
                                        }
                                    }

                                } else {
                                    mFreshNewsList.addAll(freshNewsList);
                                }

                                mListView.setPullLoadEnable(true);
                                mListView.setPullRefreshEnable(true);
                            }
                        } else {
                            mListView.setPullLoadEnable(false);
                        }

                        if (page == 1) {
                            mFreshNewsAdapter.notifyDataSetInvalidated();
                            mListView.stopRefresh();
                        } else {
                            mFreshNewsAdapter.notifyDataSetChanged();
                            mListView.stopLoadMore();
                        }

                        // 设置刷新时间
                        SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                        String refreshTime = mDateFormat.format(System.currentTimeMillis());
                        mListView.setRefreshTime(refreshTime);
                    }
                });

            }

            @Override
            public void onFail(int errorCode) {
                LogUtil.i(TAG, "freshNewsList errorCode = " + errorCode);

            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }
   与前面新鲜事界面的数据请求区别在于添加了下面这行代码:
  parameter.put("uid", uid + ""); // 支持传入当前用户的一个好友ID,表示获取此好友的新鲜事,如果不传,默认为获取当前用户的新鲜事 
    2、运行效果图如下:

    上一篇中的新鲜事界面如下:

    


  点击好友(刘斌)的图像,其个人主页如下:



  点击好友(任少平)的图像,其个人主页如下:



点击好友(谭静)的图像,其个人主页如下:


   向上滑动,如下图:



四、完整源码

   有关布局文件在前面已贴出,这里主要贴出个人主页(PersonalHomepageActivity)的源码,方便大家查阅。

package com.everyone.android.ui;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.everyone.android.R;
import com.everyone.android.api.NetworkBaseActivity;
import com.everyone.android.bitmap.ImageLoader;
import com.everyone.android.callback.ParseCallback;
import com.everyone.android.callback.ResultCallback;
import com.everyone.android.entity.FreshNews;
import com.everyone.android.entity.ImageInfo;
import com.everyone.android.net.AsyncBaseRequest;
import com.everyone.android.net.AsyncHttpsPost;
import com.everyone.android.ui.freshnews.FreshNewsAdapter;
import com.everyone.android.utils.Constant;
import com.everyone.android.utils.LogUtil;
import com.everyone.android.widget.TopMenuNavbar;
import com.everyone.android.widget.XListView;
import com.everyone.android.widget.XListView.IXListViewListener;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * 功能描述:个人主页(当前登录用户的个人主页或者好友的个人主页)
 * @author android_ls
 */
public class PersonalHomepageActivity extends NetworkBaseActivity implements IXListViewListener, OnClickListener {

    /**
     * LOG打印标签
     */
    private static final String TAG = PersonalHomepageActivity.class.getSimpleName();

    private TopMenuNavbar topMenuNavbar;
  
    private XListView mListView;

    private FreshNewsAdapter mFreshNewsAdapter;

    /**
     * 新鲜事信息集合
     */
    private LinkedList<FreshNews> mFreshNewsList = new LinkedList<FreshNews>();
    
    /**
     * 用户信息唯一标识
     */
    private int uid;
    
    /**
     * 每一页记录数,默认值为30,最大50 
     */
    private int pageCount = 30;

    /**
     * 当前获取第几页,默认值为1
     */
    private int page = 1;
    
    private LayoutInflater mInflater;
    
    // 用户图像
    private ImageView ivIconView;

    // 用户名
    private TextView tvName;

    // 表示该用户是否为星级用户 1表示该用户是星级用户,0表示否
    private ImageView ivStar;

    // 用户状态信息
    private TextView tvStatusContent;

    private Button btnVip;
    
    /**
     * 发表的新鲜事,默认请求所有类型的新鲜事
     */
    private static final String FRESH_NEWS_TYPE_ALL = "10,11,20,21,22,23,30,31,32,33,34,35,36";
    
    /**
     * 新鲜事类型,默认为当前所支持的全部类型
     */
    private String fresh_news_type = FRESH_NEWS_TYPE_ALL;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    protected int getLayoutId() {
        return R.layout.personal_homepage;
    }

    @Override
    protected void setupViews() {
        topMenuNavbar = (TopMenuNavbar) this.findViewById(R.id.rl_top_menu_navbar);
        topMenuNavbar.tvRightOperationName.setVisibility(View.GONE);
        topMenuNavbar.ivRightLine.setVisibility(View.GONE);

        // 将顶部左侧的menu图标换成back图标
        LinearLayout llBackMenu = topMenuNavbar.llShowMenu;
        ImageView ivBack = (ImageView) llBackMenu.findViewById(R.id.iv_back);
        ivBack.setImageResource(R.drawable.v5_0_1_flipper_head_back);

        // 将顶部右侧的刷新按钮换成下拉菜单图标
        LinearLayout llDownOperation = topMenuNavbar.mLlRefresh;
        ImageView ivOperation = (ImageView) llDownOperation.findViewById(R.id.iv_refresh);
        ivOperation.setImageResource(R.drawable.v5_0_1_flipper_head_menu);
        
        llBackMenu.setOnClickListener(this);
        llDownOperation.setOnClickListener(this);
        topMenuNavbar.mLlDownList.setOnClickListener(this);
        
        mListView = (XListView) this.findViewById(R.id.listview);
        mListView.setPullLoadEnable(false);
        mListView.setPullRefreshEnable(false);
        mListView.setXListViewListener(this);

        mInflater = LayoutInflater.from(this.getContext());
        LinearLayout mHeadView = (LinearLayout) mInflater.inflate(R.layout.personal_homepage_head, null);
        mListView.addHeaderView(mHeadView);

        mFreshNewsAdapter = new FreshNewsAdapter(this, mFreshNewsList);
        mListView.setAdapter(mFreshNewsAdapter);

        tvName = (TextView) mHeadView.findViewById(R.id.tv_name);
        ivIconView = (ImageView) mHeadView.findViewById(R.id.iv_icon);
        ivStar = (ImageView) mHeadView.findViewById(R.id.iv_star);
        tvStatusContent = (TextView) mHeadView.findViewById(R.id.tv_status_content);
        btnVip = (Button) mHeadView.findViewById(R.id.btn_vip);
    }

    @Override
    protected void initialized() {
        // TODO Auto-generated method stub
        uid = this.getIntent().getIntExtra("actor_id", -1);
        LogUtil.i(TAG, "uid = " + uid);
        
        getProfileInfo();
        getUserImage();
        getFreshNews();
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

        switch (v.getId()) {
        case R.id.ll_back:
            onBackPressed();
            break;

        default:
            break;
        }
    }

    // 下拉刷新
    @Override
    public void onRefresh() {
        page = 1;
        getFreshNews();
    }

    // 加载更多
    @Override
    public void onLoadMore() {
        page++;
        getFreshNews();
    }
    
    /**
     * 获取用户个人主页的信息
     */
    public void getProfileInfo() {
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);

        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML
        parameter.put("call_id", "1.0"); // 请求队列号

        parameter.put("method", "users.getProfileInfo");
        parameter.put("uid", uid + ""); // 个人主页用户的Id 
        parameter.put("fields", "base_info,status"); // 需要获取的信息的字段列表,各个字段用逗号隔开。
        AsyncHttpsPost asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public Object parse(String json) throws JSONException {
                LogUtil.i(TAG, "json = " + json);
                final JSONObject jsonObject = new JSONObject(json);
                
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        String name = jsonObject.optString("name");
                        LogUtil.i(TAG, "name = " + name);
                        
                        String headurl = jsonObject.optString("headurl");
                        LogUtil.i(TAG, "headurl = " + headurl);

                        int star = jsonObject.optInt("star");
                        LogUtil.i(TAG, "star = " + star);
                      
                        JSONObject jsonStatus = jsonObject.optJSONObject("status");
                        String status = jsonStatus.optString("content");
                        LogUtil.i(TAG, "status = " + status);
                        
                        tvName.setText(name);
                        tvStatusContent.setText(status);
                        
                        if (star == 1) {
                            ivStar.setVisibility(View.VISIBLE);
                        }

                        // 加载用户图像
                        /*ImageInfo imgInfo = new ImageInfo(ivIconView, headurl);
                        new ImageLoader(PersonalHomepageActivity.this).displayImage(imgInfo);*/
                        
                    }
                });

                return null;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(final Object obj) {
              /* {
                    "uid":221659942,
                    "status":{"content":"我才知道草莓翻转,是这个意思(偷笑) 转自谭静:明天最后一门考试,结束后,就真的迎来暑假啦~~哇卡卡卡~~~下学期也终于木有课了~~~(twg)(大笑)(ys)(流口水)","time":"2013-07-02 14:37:01"},
                    "star":1,
                    "network_name":"西北大学",
                    "headurl":"http://hdn.xnimg.cn/photos/hdn421/20130614/1350/tiny_cm9Q_ec73000461fa113e.jpg",
                    "name":"谭静",
                    "base_info":{"birth":{"birth_month":3,"birth_day":21,"birth_year":"1987"},"hometown":{"province":"河北","city":"唐山市"},"gender":0}
                 }*/
            }

            @Override
            public void onFail(int errorCode) {
                LogUtil.i(TAG, "freshNewsList errorCode = " + errorCode);

            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }

    /**
     * 获取用户的图像
     * @param uid 用户Id
     */
    public void getUserImage(){
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);
        
        // 获取用户信息所需的参数
        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML,推荐使用JSON,缺省值为XML 
        parameter.put("call_id", "1.0"); // 请求队列号 
        
        parameter.put("method", "users.getInfo"); // 你要访问那个接口,我们肯定调用用获取用户的信息的接口咯,该接口支持批量获取。
        parameter.put("uids", uid + ""); // 个人主页用户的Id 
        parameter.put("fields", "zidou,vip,mainurl"); // 返回的字段列表,可以指定返回那些字段,用逗号分隔。
        
        AsyncBaseRequest asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public Object parse(String json) throws JSONException {
                LogUtil.i(TAG, "---------->json = " + json);

                JSONArray jsonArray = new JSONArray(json);
                JSONObject jsonObject = jsonArray.getJSONObject(0);
                int vip = jsonObject.optInt("vip");
                LogUtil.i(TAG, "vip = " + vip);

                int zidou = jsonObject.optInt("zidou");
                LogUtil.i(TAG, "zidou = " + zidou);
                
                String headurl = jsonObject.optString("mainurl");
                LogUtil.i(TAG, "headurl = " + headurl);
               
                if (TextUtils.isEmpty(headurl)) {
                    LogUtil.i(TAG, "用户图像对应的URL为null");
                    return null;
                }
                
                final String imageUrl = headurl;
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {
                        ImageInfo imgInfo = new ImageInfo(ivIconView, imageUrl);
                        new ImageLoader(PersonalHomepageActivity.this).displayImage(imgInfo);   
                    }
                });
                
                return null;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(Object obj) {
                // 正常情况下返回的JSON字符串
                /*[
                 {
                     "uid":221659942,
                     "vip":1,
                     "mainurl":"http://hdn.xnimg.cn/photos/hdn221/20130614/1350/h_main_hIfE_e8e9000001ad113e.jpg",
                     "zidou":0
                  }
                ]*/
                
                // 异常情况下返回的JSON字符串
               /* [
                 {
                     "uid":600038849,
                     "tinyurl":"http://hdn.xnimg.cn/photos/hdn221/20110212/1700/h_tiny_2ZyG_4a320001f9f62f75.jpg",
                     "vip":1,
                     "sex":1,
                     "name":"折翼の天使",
                     "star":1,
                     "headurl":"http://hdn.xnimg.cn/photos/hdn221/20110212/1700/h_head_jMyd_4a320001f9f62f75.jpg",
                     "zidou":0
                  }
                ]*/

            }

            @Override
            public void onFail(int errorCode) {
                // TODO Auto-generated method stub
            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }
    
    /**
     * 向服务器端请求新鲜事的数据
     */
    public void getFreshNews() {
        String accessToken = mAuthTokenManager.getAccessToken();
        LogUtil.e(TAG, "accessToken = " + accessToken);

        Map<String, String> parameter = new HashMap<String, String>();
        parameter.put("v", "1.0"); // API的版本号,固定值为1.0 
        parameter.put("access_token", accessToken); // OAuth2.0验证授权后获得的token。
        parameter.put("format", "JSON"); // 返回值的格式。请指定为JSON或者XML
        parameter.put("call_id", "1.0"); // 请求队列号
        parameter.put("method", "feed.get");
        parameter.put("type", fresh_news_type); // 新鲜事的类别,多个类型以逗号分隔,type列表 
        parameter.put("uid", uid + ""); // 支持传入当前用户的一个好友ID,表示获取此好友的新鲜事,如果不传,默认为获取当前用户的新鲜事 
        parameter.put("page", page + ""); // 支持分页,指定页号,页号从1开始,默认值为1 
        parameter.put("count", pageCount + ""); // 支持分页,每一页记录数,默认值为30,最大50 
        AsyncHttpsPost asyncHttpsPost = new AsyncHttpsPost(Constant.API_SERVER_URL, parameter, new ParseCallback() {

            @Override
            public LinkedList<FreshNews> parse(String json) throws JSONException {
                LogUtil.i(TAG, "json = " + json);
                if ("[]".equals(json)) {
                    return null;
                }

                Gson gson = new Gson();
                java.lang.reflect.Type type = new TypeToken<LinkedList<FreshNews>>() {
                }.getType();
                LinkedList<FreshNews> freshNewsList = gson.fromJson(json, type);

                LogUtil.e(TAG, "freshNewsList = " + freshNewsList.size());
                return freshNewsList;
            }
        }, new ResultCallback() {

            @Override
            public void onSuccess(final Object obj) {
                mHandler.post(new Runnable() {

                    @Override
                    public void run() {

                        if (obj != null && obj instanceof LinkedList) {
                            @SuppressWarnings("unchecked")
                            LinkedList<FreshNews> freshNewsList = (LinkedList<FreshNews>) obj;
                            if (freshNewsList.size() > 0) {
                                // 下拉刷新的数据去重复处理
                                if (page == 1 && mFreshNewsList.size() > 0) {
                                    for (FreshNews freshNews : freshNewsList) {
                                        boolean flage = false;
                                        for (FreshNews fresh : mFreshNewsList) {
                                            if(freshNews.getPost_id() == fresh.getPost_id()){
                                                flage = true;
                                            }
                                        }
                                        
                                        if(flage == false){
                                            mFreshNewsList.addFirst(freshNews);
                                        }
                                    }

                                } else {
                                    mFreshNewsList.addAll(freshNewsList);
                                }

                                mListView.setPullLoadEnable(true);
                                mListView.setPullRefreshEnable(true);
                            }
                        } else {
                            mListView.setPullLoadEnable(false);
                        }

                        if (page == 1) {
                            mFreshNewsAdapter.notifyDataSetInvalidated();
                            mListView.stopRefresh();
                        } else {
                            mFreshNewsAdapter.notifyDataSetChanged();
                            mListView.stopLoadMore();
                        }

                        // 设置刷新时间
                        SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
                        String refreshTime = mDateFormat.format(System.currentTimeMillis());
                        mListView.setRefreshTime(refreshTime);
                    }
                });

            }

            @Override
            public void onFail(int errorCode) {
                LogUtil.i(TAG, "freshNewsList errorCode = " + errorCode);

            }
        });

        mDefaultThreadPool.execute(asyncHttpsPost);
        mAsyncRequests.add(asyncHttpsPost);
    }
    
}


五、应网友的要求,贴出目前项目的包结构图如下:


这一篇就先聊到这里吧,后面的待续。不早了,我要睡觉了。晚安!









 

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值