新浪微博客户端开发详解(三)

上一篇博文中详细讲解了auth2.0的认证过程,本篇博文会详细讲解获取微博数据并显示出来的效果。

首先看效果图:

新浪微博客户端开发详解(三)_第1张图片

微博数据获取之后展示效果如图所示。

(一)

首先我们从新浪微博的开放平台说起。
身份认证之后,开发者会有三十组接口可以调用。

微博普通读取接口
  • statuses/public_timeline
  • statuses/friends_timeline
  • statuses/home_timeline
  • statuses/user_timeline
  • statuses/repost_timeline
  • statuses/repost_by_me
  • statuses/mentions
  • statuses/show
  • statuses/querymid
  • statuses/queryid
  • statuses/hot/repost_daily
  • statuses/hot/repost_weekly
  • statuses/hot/comments_daily
  • statuses/hot/comments_weekly
  • statuses/friends_timeline/ids
  • statuses/bilateral_timeline
  • statuses/user_timeline/ids
  • statuses/repost_timeline/ids
  • statuses/mentions/ids
  • statuses/count
  • statuses/go






上面所示的接口是三十组接口中的一组接口,可以说是一类接口,这些接口是获取微博数据的,读取接口。意思就是说获取到微博数据。

我在这里详细讲解一个接口,剩下的接口举一反三就可以的,道理是一样的。

点击第二个接口链接,进入到该接口的详细说明的网页,详细展示如下:

2/statuses/friends timeline

statuses/friends_timeline

获取当前登录用户及其所关注用户的最新微博  

//这里是该接口的作用的说明,该接口实现什么样的功能

URL

https://api.weibo.com/2/statuses/friends_timeline.json        

 //这里是该接口的具体的url,向服务器请求就是向服务器的该接口请求,实现获取当前登录用户及其所关注用户的最新微博的功能

支持格式

JSON 

//这里说明的是请求的参数的格式,使用的是JSON格式数据向服务器发 

//送参数,这里说明一下,新浪微博的开放接口统一使用JSON格式数 

//据,服务器返回的数据也是JSON格式的,需要对JSON数据进行解

 //析,不过JSON格式数据非常简单

HTTP请求方式

GET 

//这里指明了向服务器请求的方式,使用GET方式进行请求

是否需要登录

 //这里指明了该接口是需要用户登录之后才可以获取该接口提供的数据, 

//如果这里是“否”,说明该接口可以在用户没有登录的情况下实现该接 

//口提供的功能。例如:分享接口就不用用户登录就可以实现。
关于登录授权,参见 如何登录授权

访问授权限制

访问级别:普通接口 
频次限制: 
关于频次限制,参见 接口访问权限说明


//这里说明该接口的访问级别,一般的开发者身份认证成功之后会有三十

//组接口可以使用,不过是普通接口,还有一些高级接口一般开发者还不

//能使用。什么情况下可以使用呢?可以到我的应用->接口管理->申请权 //限里面可以申请高级接口。

//另外需要说明的是频次限制,这个是该接口的访问频率的限制次数,这  

//样的限制很明显就是为了安全嘛。不过不用担心,这个是开发阶段才有 

//这样的限制。

请求参数 

//请求参数明什么说的了,人家写的很详细

  必选 类型及范围 说明
source false string 采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。
access_token false string 采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。
since_id false int64 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
max_id false int64 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。
count false int 单页返回的记录条数,最大不超过100,默认为20。
page false int 返回结果的页码,默认为1。
base_app false int 是否只获取当前应用的数据。0为否(所有数据),1为是(仅当前应用),默认为0。
feature false int 过滤类型ID,0:全部、1:原创、2:图片、3:视频、4:音乐,默认为0。
trim_user false int 返回值中user字段开关,0:返回完整user字段、1:user字段仅返回user_id,默认为0。

注意事项

调用样例及调试工具

API测试工具

返回结果 

//返回结果使用的是JSON格式的数据

JSON示例

{ "statuses": [ { "created_at": "Tue May 31 17:46:55 +0800 2011", "id": 11488058246, "text": "求关注。", "source": "新浪微博", "favorited": false, "truncated": false, "in_reply_to_status_id": "", "in_reply_to_user_id": "", "in_reply_to_screen_name": "", "geo": null, "mid": "5612814510546515491", "reposts_count": 8, "comments_count": 9, "annotations": [], "user": { "id": 1404376560, "screen_name": "zaku", "name": "zaku", "province": "11", "city": "5", "location": "北京 朝阳区", "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。", "url": "http://blog.sina.com.cn/zaku", "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1", "domain": "zaku", "gender": "m", "followers_count": 1204, "friends_count": 447, "statuses_count": 2908, "favourites_count": 0, "created_at": "Fri Aug 28 00:00:00 +0800 2009", "following": false, "allow_all_act_msg": false, "remark": "", "geo_enabled": true, "verified": false, "allow_all_comment": true, "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1", "verified_reason": "", "follow_me": false, "online_status": 0, "bi_followers_count": 215 } }, ... ], "ad": [ { "id": 3366614911586452, "mark": "AB21321XDFJJK" }, ... ], "previous_cursor": 0, // 暂时不支持 "next_cursor": 11488013766, // 暂时不支持 "total_number": 81655 }

关于错误返回值与错误代码,参见 错误代码说明

返回字段说明

返回值字段 字段类型 字段说明
created_at string 微博创建时间
id int64 微博ID
mid int64 微博MID
idstr string 字符串型的微博ID
text string 微博信息内容
source string 微博来源
favorited boolean 是否已收藏,true:是,false:否
truncated boolean 是否被截断,true:是,false:否
in_reply_to_status_id string (暂未支持)回复ID
in_reply_to_user_id string (暂未支持)回复人UID
in_reply_to_screen_name string (暂未支持)回复人昵称
thumbnail_pic string 缩略图片地址,没有时不返回此字段
bmiddle_pic string 中等尺寸图片地址,没有时不返回此字段
original_pic string 原始图片地址,没有时不返回此字段
geo object 地理信息字段 详细
user object 微博作者的用户信息字段 详细
retweeted_status object 被转发的原微博信息字段,当该微博为转发微博时返回 详细
reposts_count int 转发数
comments_count int 评论数
attitudes_count int 表态数
mlevel int 暂未支持
visible object 微博的可见性及指定可见分组信息。该object中type取值,0:普通微博,1:私密微博,3:指定分组微博,4:密友微博;list_id为分组的组号
pic_ids object 微博配图ID。多图时返回多图ID,用来拼接图片url。用返回字段thumbnail_pic的地址配上该返回字段的图片ID,即可得到多个图片url。
ad object array 微博流内的推广微博ID

以上便是对于一个接口的详细说明了。看懂了一个接口,搞明白之后,其他的接口跟这个异曲同工,举一反三,就很容易看懂,没什么问题。真正带开发只用看参数和返回值就可以了。

(二)

下面我贴出该接口的实现类。

public class HomeAcitivity extends Activity
{
	private ListView listview ;
	private ProgressBar progressbar;
	private List statuses;//每条微博看作一个对象Status,获取的好友微博使用List保存
	private Intent intent;
	private int postionIndex;
	private Oauth2AccessToken mAccessToken;//这个类非常关键,三十组接口的调用均需要使用该类中所保存的Token和code值、expire值等
	private WeiboManager weibomanager;//这个是自动义的微博管理类,使用该类获取或者操作微博。就是说一切对于微博的操作均在微博管理类中实现,稍后会贴出该类的代码
	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler()
//这是android中的消息传递机制,因为访问网络数据在最新的android sdk中是不允许在主线程中访问网络资源,必须另外开启线程,当另外的线程获取到资源之后,利用handler把数据返回到主线程,下面的message就是封装了利用handler传递到主线程的数据。
	{
		@SuppressWarnings({ "unchecked", "static-access" })
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
			case 0x111:
				progressbar.setVisibility(View.GONE);
				listview.setVisibility(View.VISIBLE);
				statuses = (List)msg.obj;//获取成功之后,利用message封装数据,利用handler把数据传递到主线程
				msg.obj = statuses;		
			listview.setAdapter(new WeiboListAdapter(HomeAcitivity.this,statuses,R.id.publicStatus));
		handler.sendMessage(msg);}}.start();//初始状态下,加载新微博
		listview.setOnItemLongClickListener(new OnItemLongClickListener() 
			//对每条微博设置一个监听器,长按可以弹出一个菜单项,菜单项中包括刷新微博、查看单条微博、退出等。
		{	@Override
			public boolean onItemLongClick(AdapterView arg0, View v, int postion, long id){
			boolean bl = listview.showContextMenu();
			postionIndex = postion;
			return true;
			}
		});
		listview.setOnCreateContextMenuListener(new OnCreateContextMenuListener(){
//这个是初始化菜单项,利用R。menu.menu实现,需要在res资源文件夹下的建立一个固定名字为
//menu的文件夹,该文件夹下有一个固定名字的menu.xml实现,如果各位看官不知道这个怎么回事,请另外搜索如何定义菜单项
		    @Override    
		    public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo info) {     
		    	MenuInflater inflator = getMenuInflater();
				inflator.inflate(R.menu.menu,menu);
		        menu.setHeaderTitle("菜单");
		    }
		});
		mAccessToken = AccessTokenKeeper.readAccessToken(HomeAcitivity.this);//这个是获取Token的工具类,在sinasdk-core.jar中已经实现好了,可以直接使用
	}
	@Override
	public boolean onContextItemSelected(MenuItem item)//这个方法就是对定义的菜单中的每一项可以实现的功能
	{
		switch (item.getItemId())
		{
		case R.id.refresh://刷新
			new Thread()
			{
				@SuppressWarnings("static-access")
				@Override
				public void run()
				{
					List statuses1 = weibomanager.getHomeTimeline();
					Message msg = new Message();
					msg.obj = statuses1;
					msg.what = 0x110;
					handler.sendMessage(msg);
				}
			}.start();
			break;
		case R.id.detail://查看微博
			WeiboListAdapter weibolistadapter = new WeiboListAdapter(HomeAcitivity.this,statuses,R.id.detail);
			Status status = weibolistadapter.getItem(postionIndex);
			if(status != null)
			{
				Bundle bundle = new Bundle();
				bundle.putSerializable("status", status);
				Intent intent = new Intent(HomeAcitivity.this,StatusDetailActivity.class);
				intent.putExtras(bundle);
				startActivity(intent);
			}else {		}
			break;
		case R.id.exit://退出
			AlertDialog.Builder alertdialog = new AlertDialog.Builder(HomeAcitivity.this);
			alertdialog.setTitle("退出微博");
			alertdialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
			{
				@Override
				public void onClick(DialogInterface arg0, int arg1)
				{
					AccessTokenKeeper.clear(HomeAcitivity.this);
					Log.d("clear==",mAccessToken.toString());
					AccountAPI accountapi = new AccountAPI(mAccessToken);
					requestListener requestLis = new requestListener();
					accountapi.endSession(requestLis);
					String json = null;
					json = requestLis.get();
					Message msg2 = new Message();
					msg2.obj = json + "null";
					msg2.what = 0x120;
					handler.sendMessage(msg2);
					finish();
				}
			});
			alertdialog.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener()
			{
				@Override
				public void onClick(DialogInterface dialog, int which)
				{		
				}
			});
			alertdialog.show();
			break;
		default:
			break;
		}
		return super.onContextItemSelected(item);
		}
}

上面的代码是activity实现类,根据我的注释应该还是很容易理解的,不过里面用到了weiboManager类和WeiboListAdapter适配器,在此详细说明WeiboManager类和WeiboListAdapter类.

(三)

WeiboManager类比较简单,使用的是已经实现好的工具类。先看代码:

public class WeiboManager implements Constants
{
	private static String json;
	private static List statuses = null;
	private static Oauth2AccessToken mAccessToken;
	private static StatusesAPI statusesapi;
	public WeiboManager(){}//默认构造器
	public WeiboManager(Context context)//需要Context参数的构造器,这里使用Context最好
	{
		mAccessToken = AccessTokenKeeper.readAccessToken(context);
		statusesapi= new StatusesAPI(mAccessToken);
		//微博接口api,这个工具类是在sinasdk.jar包中已经封装好了,可以直接使用,这个jar包的下载地址我会在
		//博文最后给出jar包的下载地址,供大家使用。当然这个jar包的工具类远不止这一个
		//AccountAPI CommentsAPI CommonAPI FavoritesAPI FriendshipsAPI PlaceAPI RegisterAPI等等这个api接口均在
		//该jar包中定义好,开发者只需给定参数调用接口即可。
	}

	@SuppressWarnings("unchecked")
	public static List getHomeTimeline()
	{
		/**
		* StatusesAPI是微博api接口,里面定义的方法有很多,
		*	publicTimeline 返回最新的公共微博
		*	friendsTimeline 获取当前登录用户及其所关注用户的最新微博
		*	friendsTimelineIds 获取当前登录用户及其所关注用户的最新微博的ID
		*	userTimeline 获取某个用户最新发表的微博列表(与下面这个方法参数不同)
		*	userTimeline 获取某个用户最新发表的微博列表
		*	repostTimeline 获取指定微博的转发微博列表
		*	等等 这些方法均是在StatusesAPI工具类中已经实现好的,我在这里直接使用homeTimeline获取好友微博列表
		*	的方法。由于并不是做很大的应用,这里只是学习测试,所以这里的参数也是给定的。
		*	
		*	homeTimeline方法中的参数说明如下:
		* 获取当前登录用户及其所关注用户的最新微博
		*	public void homeTimeline( long since_id, long max_id, int count, int page,
		*		boolean base_app, FEATURE feature, boolean trim_user, RequestListener listener)
		* @param since_id 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0。
		* @param max_id 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。
		* @param count 单页返回的记录条数,默认为50。
		* @param page 返回结果的页码,默认为1。
		* @param base_app 是否只获取当前应用的数据。false为否(所有数据),true为是(仅当前应用),默认为false。
		* @param feature 过滤类型ID,0:全部、1:原创、2:图片、3:视频、4:音乐,默认为0。
		* @param trim_user 返回值中user字段开关,false:返回完整user字段、true:user字段仅返回user_id,默认为false。
		* @param listener
		*	对于RequestListener监听器我在详细说明一下,如果大家的记性好的话,这个监听器大家是用到过的。
		*	在进行auth2.0授权认证的时候,获取Token值的时候,这个Token值得获取就是通过监听器回调得到的,原理还这里用
		*	到的是一样的。
		*	当调用该方法的时候,会把该方法中的new RequestListener()匿名监听器对象作为参数传递,当服务器返回响应
		*	会自动的调用该监听器的方法,如果成功,调用onComplete方法,服务器返回的数据就是response参数的值
		*	如果服务器由于某种原因错误,则会调用其他的方法。
		**/
		statusesapi.homeTimeline(0L,0L,10,1,false,FEATURE.ALL,false,new RequestListener(){
			@Override
			public void onComplete(String response)
			{
				if (response == null)
				{
					return;
				}
				this.json = response;//服务器返回的数据是JSON格式的字符串数据,
				statuses = JSONAndObject.convert(Status.class, json, "statuses");//这里把json字符串数据转化为微博对象
			}
			@Override
			public void onComplete4binary(ByteArrayOutputStream responseOS)
			{
				// TODO Auto-generated method stub
			}
			@Override
			public void onIOException(IOException e)
			{
				// TODO Auto-generated method stub
			}
			@Override
			public void onError(WeiboException e)
			{
				// TODO Auto-generated method stub
			}
		});
		return statuses;
	}
}

	/**
	*
	*该工具类就是把json字符串转化为微博对象,是一个工具类,可以直接使用的。
	**/
public class JSONAndObject
{
	// 使用该方法时需要先创建一个Object,传入第1个参数
	public static Object convertSingleObject(Object obj, String json)
	{
		if (obj == null || json == null)
			return obj;
		try
		{
			// 只使用public类型字段
			Field[] fields = obj.getClass().getFields();
			if (fields != null)
			{
				JSONObject jsonObject = new JSONObject(json);

				for (Field field : fields)
				{
					try
					{
						// 如果json中没有相应的key,会抛出异常,继续扫描下一个key
						Object objValue = jsonObject.get(field.getName());
						// 字符串类型
						if (field.getType() == String.class)
						{
							field.set(obj, String.valueOf(objValue));
						}
						// long类型
						else if (field.getType() == long.class)
						{
							field.set(obj,Long.valueOf(String.valueOf(objValue)));
						}
						// int类型
						else if (field.getType() == int.class)
						{
							field.set(obj,Integer.valueOf(String.valueOf(objValue)));
						}
						// boolean类型
						else if (field.getType() == boolean.class)
						{
							field.set(obj, Boolean.getBoolean(String.valueOf(objValue)));
						}
						// Object类型(WeiboObject类型)
						else
						{
							Object fieldObject = field.getType().newInstance();
							if (fieldObject instanceof WeiboObject)
							{
								convertSingleObject(fieldObject,String.valueOf(objValue));
								field.set(obj, fieldObject);
							}
						}
					}
					catch (Exception e)
					{
						// TODO: handle exception
					}
				}
			}
		}
		catch (Exception e)
		{
		}
		return obj;
	}

	// 将json字符串转换为List
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List convert(Class c, String json, String propertyName)
	{
		List objs = null;
		if (c == null || json == null)
			return objs;
		try
		{
			// 只使用public类型字段
			Field[] fields = c.getFields();
			if (fields != null)
			{
				String jsonStr = json;
				if (propertyName != null)
				{
					JSONObject jsonObject = new JSONObject(json);
					jsonStr = jsonObject.get(propertyName).toString();
				}
				JSONArray jsonArray = new JSONArray(jsonStr);
				objs = new ArrayList();
				for (int i = 0; i < jsonArray.length(); i++)
				{
					Object obj = c.newInstance();
					objs.add(obj);
					convertSingleObject(obj, jsonArray.getString(i));
				}
			}
		}
		catch (Exception e)
		{
			Log.d("convert==", e.getMessage());
		}
		return objs;
	}

	public static String convertSingleObjectToJson(Object obj)
	{
		String json = null;
		if (obj == null)
		{
			return json;
		}
		Field[] fields = obj.getClass().getFields();
		json = "{";
		for (int i = 0; i < fields.length; i++)
		{
			try
			{
				Field field = fields[i];
				if (field.getType() == String.class)
				{
					String temp = ((field.get(obj) == null) ? "" : String
							.valueOf(field.get(obj)));

					temp = temp.replaceAll("\"", "\\\\\"");
					json += "\"" + field.getName() + "\":\"" + temp + "\"";
				}
				// long类型
				else if (field.getType() == long.class)
				{
					json += "\"" + field.getName() + "\":" + field.getLong(obj);
				}
				// int类型
				else if (field.getType() == int.class)
				{
					json += "\"" + field.getName() + "\":" + field.getInt(obj);
				}
				// boolean类型
				else if (field.getType() == boolean.class)
				{
					json += "\"" + field.getName() + "\":"
							+ field.getBoolean(obj);
				}
				// Object类型(WeiboObject类型)
				else
				{
					Object fieldObject = field.get(obj);
					if (fieldObject instanceof WeiboObject)
					{
						json += "\"" + field.getName() + "\":"
								+ convertSingleObjectToJson(fieldObject);
					}
					else
					{
						continue;
					}
				}
				if (i < fields.length - 1)
				{
					json += ",";
				}
			}
			catch (Exception e)
			{
				// TODO: handle exception
			}
		}
		json += "}";
		return json;
	}

	public static String convertObjectToJson(Object obj, String propertyName)
	{
		String json = null;
		if (obj == null)
			return json;
		if (obj instanceof List)
		{
			List list = (List) obj;
			if (propertyName != null)
			{
				// 包含一个属性的对象,这个属性是对象数组
				json = "{\"" + propertyName + "\":[";
			}
			else
			{
				// 对象数组
				json = "[";
			}
			for (int i = 0; i < list.size(); i++)
			{
				Object item = list.get(i);
				json += convertSingleObjectToJson(item);
				if (i < list.size() - 1)
					json += ",";
			}
			if (propertyName != null)
			{
				json += "]}";
			}
			else
			{
				json = "]";
			}
		}
		return json;
	}
}

(四)

下面给出WeiboListAdapter类的实现代码,大家应该对BaseAdapter很熟悉了。
public class WeiboListAdapter extends BaseAdapter implements Serializable
{
	Activity activity;
	protected LayoutInflater layoutInflater;
	protected int faceType;
	protected List statuses;
	public static View view = null;
	@Override
	public int getCount()
	{
		return statuses.size();
	}
	@Override
	public Status getItem(int position)
	{
		return statuses.get(position);
	}
	@Override
	public long getItemId(int position)
	{
		return position;
	}
	//这里使用的是图片下载机制,使用异步方式下载
	public static Drawable loadImage(String url,ImageView imgeview)
	{
		AsyncImageLoader asyncImageLoader = new AsyncImageLoader();
		Drawable drawable = asyncImageLoader.loadDrawable(url,imgeview , new ImageCallback()
		{  
		    @Override  
		    public void imageLoaded(Drawable imageDrawable, ImageView imageView,String imageUrl)
		    {  
		    	imageView.setImageDrawable(imageDrawable);
		    }
		});
		return drawable;
	}
	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		if (convertView == null)
		{
			convertView = layoutInflater.inflate(R.layout.weibosdkdemo_list_item, null);
		}
		View weiboListItem = convertView.findViewById(R.id.linearlayout_weibo_list_item);
		if (position < statuses.size())
		{
			weiboListItem.setVisibility(View.VISIBLE);
			Status status = statuses.get(position);
			TextView statusText = (TextView) convertView.findViewById(R.id.textview_text);//微博文本内容
			TextView name = (TextView) convertView.findViewById(R.id.textview_name);//微博作者
			TextView createdAt = (TextView) convertView.findViewById(R.id.textview_created_at);//微博发布时间
			
			ImageView profileImage = (ImageView)convertView.findViewById(R.id.imageview_profile_image);//微博作者头像
			profileImage.setImageResource(R.drawable.portrait);//设置微博作者头像(采用默认头像)
			
			ImageView picture = (ImageView) convertView.findViewById(R.id.imageview_picture);//微博带图像标志
			ImageView statusImage = (ImageView) convertView.findViewById(R.id.imageview_status_image);//微博内容图片
			ImageView verified = (ImageView) convertView.findViewById(R.id.imageview_verified);//认证用户图标
			verified.setVisibility(View.GONE);
			if (status.user != null)//如果微博作者不空
			{
				Tools.userVerified(verified, status.user.verified_type);
			}

			LinearLayout insideContent = (LinearLayout) convertView
					.findViewById(R.id.linearlayout_inside_content);//微博内容的线性布局
			ImageView retweetdetailImage = (ImageView) convertView
					.findViewById(R.id.imageview_retweetdetail_image);//转发微博的图片

			TextView retweetdetailText = (TextView) convertView
					.findViewById(R.id.textview_retweetdetail_text);//转发微博的文本内容
			TextView source = (TextView) convertView.findViewById(R.id.textview_source);//显示微博来源
			// 当前微博有图像,设置微博图片可见
			//如果微博中存在图片(包含转发微博中的图片),则设置图片标记可见
			//如果微博中存在图片(不是转发)则设置图片可见
			//如果转发微博中存在图片 则设置转发微博图片可见
			//初始化
			picture.setVisibility(View.INVISIBLE);
			statusImage.setVisibility(View.GONE);
			retweetdetailImage.setVisibility(View.GONE);
			if (WeiboManager.hasPicture(status))
			{
				if ( (status.thumbnail_pic != null) && (!"".equals(status.thumbnail_pic) ))//如果微博有图片
					{
						statusImage.setVisibility(View.VISIBLE);
						picture.setVisibility(View.VISIBLE);
					}
				if(status.retweeted_status != null)
				{
					if ( (status.retweeted_status.thumbnail_pic != null)
							&& (!"".equals(status.retweeted_status.thumbnail_pic)))
					{
						retweetdetailImage.setVisibility(View.VISIBLE);//如果转发微博内容有图片
						picture.setVisibility(View.VISIBLE);
					}
				}
			}else//否则设置微博图片不可见
			{
				picture.setVisibility(View.INVISIBLE);
				statusImage.setVisibility(View.GONE);
				retweetdetailImage.setVisibility(View.GONE);
			}
			// 装载图像  头像设置
			Drawable profilePortrait=null;
			if (status.user != null)
			{
				profilePortrait = loadImage(status.user.profile_image_url,profileImage);//如果微博用户存在
			}
			if(profilePortrait == null)
			{
				profileImage.setImageResource(R.drawable.portrait);
			}else
			{
	//			profileImage.setImageDrawable(profilePortrait);
			}
			profilePortrait=null;//再次初始化
			//装载微博图片,默认情况下为GONE
			Drawable profileStatusImage = null;
			if (status != null && status.thumbnail_pic!="")
			{
				profileStatusImage = loadImage(status.thumbnail_pic,statusImage);
			}
			profileStatusImage = null;
			statusText.setText(Tools.changeTextToFace(activity,Html.fromHtml(Tools.atBlue(status.text))));//设置微博文本内容,同时对字符进行处理
			if (status.user != null)
				name.setText(status.user.name);//设置微博作者
			
			createdAt.setText(Tools.getTimeStr(status.getCreatedAt(),new Date()));//设置微博发布时间
			source.setText("来自  " + status.getTextSource());//设置微博来源
			if (status.retweeted_status != null	&& status.retweeted_status.user != null)//如果是转发微博,并且转发微博的作者存在
			{
				insideContent.setVisibility(View.VISIBLE);//设置转发微博内容的线性布局可见
				retweetdetailText.setText(Html.fromHtml(Tools.atBlue("@"
						+ status.retweeted_status.user.name + ":"
						+ status.retweeted_status.text)));//设置转发微博的文本内容,同时对字符进行处理
				Drawable profileStatusThumbnailPic = null;
				if (status != null && status.retweeted_status.thumbnail_pic != "")
				{
					profileStatusThumbnailPic = loadImage(status.retweeted_status.thumbnail_pic,retweetdetailImage);
				}
				profileStatusThumbnailPic = null;
			}else//否则设置微博内容的线性布局不可见
			{
				insideContent.setVisibility(View.GONE);
			}
		}
		else//如果获取position位置 超过了微博List的长度,设置不可见
		{
			weiboListItem.setVisibility(View.GONE);
		}
		view = convertView;
		return convertView;
	}
	
	public WeiboListAdapter(Activity activity)//构造器
	{
		this.activity = activity;
	}
	public WeiboListAdapter(Activity activity, List statuses, int faceType)
	{
		this.activity = activity;
		this.faceType = faceType;
		layoutInflater = (LayoutInflater) activity
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.statuses = new ArrayList();
		if (statuses != null)
			this.statuses.addAll(statuses);
	}
}


WeiboListAdapter类中的布局文件如下:


     
		
        

            
				
                
				
                
            
			
            
				
                

                
					
                    
					
                    
                

                
					
                    

                    
						
                        
						
                        
                    
					
                    
					
                    
                
            
        
    

(五)

在WeiboListAdapter类中使用到了AsyncImageLoader这个类,这个类的功能是异步下载图片,这个类是网上面的大神做的,我只直接拿过来用的,再次贴出来供大家学习下,由于不知道出处了,所以请原作者勿怪勿怪哈^_^

public class AsyncImageLoader
{
	/**
	 * 软引用对象,在响应内存需要时,由垃圾回收器决定是否清除此对象。软引用对象最常用于实现内存敏感的缓存。
	 */
	private HashMap> imageCache;
	public AsyncImageLoader()
	{
		imageCache = new HashMap>();
	}

	@SuppressLint("HandlerLeak")
	public Drawable loadDrawable(final String imageUrl, 
			final ImageView imageView, final ImageCallback imagecallback)
	{
		if (imageCache.containsKey(imageUrl))
		{
			// 从缓存中读取
			SoftReference softReference = imageCache.get(imageUrl);
			Drawable drawable = softReference.get();
			if (drawable != null)
			{
				return drawable;
			}
		}
		final Handler handler = new Handler()
		{
			@Override
			public void handleMessage(Message msg)
			{
				super.handleMessage(msg);
				imagecallback.imageLoaded((Drawable) msg.obj, imageView, imageUrl);
			}
		};
		new Thread()
		{
			public void run()
			{
				Drawable drawable = loadImageFromUrl(imageUrl);
				imageCache.put(imageUrl, new SoftReference(drawable));
				//这种方法性能更好。主要区别在Message对象的创建上。
				/*obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间
				* new需要重新申请,效率低,obtianmessage可以循环利用;
				*/
				Message message = handler.obtainMessage(0, drawable);
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}
	public static Drawable loadImageFromUrl(String urlPath)
	{
		URL url;
		InputStream is = null;
		try
		{
			url = new URL(urlPath);
			is = (InputStream) url.getContent();
		} catch (Exception e)
		{
			e.printStackTrace();
		}
		Drawable drawable = Drawable.createFromStream(is, "src");
		return drawable;
	}
}

这个类的代码看上去也非常简单,使用弱引用的功能,说实话,之前没有用过弱引用,现在用了一下,是不是感觉挺不错的。不过弱引用还是有一点不好的地方,因为在内存紧张的应用当中,使用弱引用会被垃圾回收机制回收,此次使用弱引用指向图片的缓存,如果垃圾回收,那么就是这张图片显示不出来了,所以当图片显示不出来的时候不仅仅是网络的问题了,还有可能是缓存或者内存的问题了。所以使用缓存-弱引用有这样的小小的不爽的地方,但是它的性能却是好的,因为总比内存溢出要好很多!

至此,一个微博列表已经实现了。马马虎虎写这么多,我也知道表述清楚了没有,还希望各位见谅哈!








你可能感兴趣的:(微博客户端)