Android仿人人客户端(v5.7.1)——个人主页(一)
2013-07-05 03:11
666 查看
转载请标明出处:http://blog.csdn.net/android_ls/article/details/9248013
声明:仿人人项目,所用所有图片资源都来源于其它Android移动应用,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。
这篇是在前面的系列文章的基础上展开的,不明白的可以先翻看下前面的文章。
一、实现个人主页顶部导航栏
1、自定义类(PersonalHomepageActivity)去继承NetworkBaseActivity,源码如下:
a.设置布局文件,源码如下:
二、实现个人主页Header部分
1、布局文件(personal_homepage.xml)中添加XListView组件
a.获取HeadView的子组件,源码如下:
d.我们运行下看看效果怎么样,效果图如下:
我们看到的用户图像好模糊哦,可是人人官方的应用运行后的效果很好啊,他们怎么实现的呢?我继续翻看人人官方提供的API,发现有users.getInfo这么个接口,编写程序调用这个接口,代码如下:
感觉是不是好了很多,我们既然已实现想要的效果,那就多从新鲜事列表的Item中点击用户图像,来回切切看,发现有问题了,有一张图片没显示出来,如下图:
什么原因呢?查看服务器端返回的JSON字符串如下:
注:获取个人主页数据,人人官方提供的接口,我觉得有待改进。最起码你不能让我为了两个字段再去请求次服务器吧。(大图像和VIP相关的字段)
三、个人主页的新鲜事的实现(基本上和前面的新鲜事界面的实现是一样的)
1、从网络请求有关当前好友的新鲜事数据,代码如下:
上一篇中的新鲜事界面如下:
点击好友(刘斌)的图像,其个人主页如下:
点击好友(任少平)的图像,其个人主页如下:
点击好友(谭静)的图像,其个人主页如下:
向上滑动,如下图:
四、完整源码
有关布局文件在前面已贴出,这里主要贴出个人主页(PersonalHomepageActivity)的源码,方便大家查阅。
五、应网友的要求,贴出目前项目的包结构图如下:
这一篇就先聊到这里吧,后面的待续。不早了,我要睡觉了。晚安!
声明:仿人人项目,所用所有图片资源都来源于其它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);
}
}
五、应网友的要求,贴出目前项目的包结构图如下:
这一篇就先聊到这里吧,后面的待续。不早了,我要睡觉了。晚安!
相关文章推荐
- Android仿人人客户端(v5.7.1)——个人主页(二)
- Android仿人人客户端(v5.7.1)——个人主页(三)
- Android仿人人客户端(v5.7.1)——个人主页(三)
- Android仿人人客户端(v5.7.1)——应用主界面之左侧面板UI实现
- [置顶] Android仿人人客户端(v5.7.1)——人人授权访问界面
- Android仿人人客户端(v5.7.1)——网络模块处理的架构
- Android仿人人客户端(v5.7.1)——新鲜事之完整篇
- 图片、缓存-Android仿人人客户端(v5.7.1)——对从服务器端(网络)获取的图片进行本地双缓存处理(编码实现)-by小雨
- Android仿人人客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图
- Android仿人人客户端(v5.7.1)开发(不错)
- [置顶] Android仿人人客户端(v5.7.1)——应用主界面之左侧面板UI实现
- Android仿人人客户端(v5.7.1)——采用RelativeLayout做父容器,实现左侧滑动菜单(一)
- [置顶] Android仿人人客户端(v5.7.1)——采用ViewGroup做父容器,实现左侧滑动菜单(三)
- Android仿人人客户端(v5.7.1)——通过HTTPS协议的POST方式获取用户的基本信息
- Android仿人人客户端(v5.7.1)——授权认证(用accessToken换取session_key、session_secret和userId)
- Android仿人人客户端(v5.7.1)——Auth授权认证(整理流程,重构代码)
- Android仿人人客户端(v5.7.1)——点击左侧菜单栏中的Item切换视图
- Android仿人人客户端(v5.7.1)——新鲜事之下拉列表(过滤项列表)
- Android仿人人客户端(v5.7.1)——项目框架新做的调整描述(项目中基类java源码)
- Android仿人人客户端(v5.7.1)——采用RelativeLayout做父容器,实现左侧滑动菜单(二)