android开发新浪微博客户端 完整攻略 [新手必读]_纯android实现微博发布图片

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

//更新users表的记录,根据UserId更新用户昵称和用户图标

public int UpdateUserInfo(String userName,Bitmap userIcon,String UserId)

{

ContentValues values = new ContentValues();

values.put(UserInfo.USERNAME, userName);

// BLOB类型

final ByteArrayOutputStream os = new ByteArrayOutputStream();

// 将Bitmap压缩成PNG编码,质量为100%存储

userIcon.compress(Bitmap.CompressFormat.PNG, 100, os);

// 构造SQLite的Content对象,这里也可以使用raw

values.put(UserInfo.USERICON, os.toByteArray());

int id= db.update(SqliteHelper.TB_NAME, values, UserInfo.USERID + “=” + UserId, null);

Log.e(“UpdateUserInfo2”,id+“”);

return id;

}

//更新users表的记录

public int UpdateUserInfo(UserInfo user)

{

ContentValues values = new ContentValues();

values.put(UserInfo.USERID, user.getUserId());

values.put(UserInfo.TOKEN, user.getToken());

values.put(UserInfo.TOKENSECRET, user.getTokenSecret());

int id= db.update(SqliteHelper.TB_NAME, values, UserInfo.USERID + “=” + user.getUserId(), null);

Log.e(“UpdateUserInfo”,id+“”);

return id;

}

//添加users表的记录

public Long SaveUserInfo(UserInfo user)

{

ContentValues values = new ContentValues();

values.put(UserInfo.USERID, user.getUserId());

values.put(UserInfo.TOKEN, user.getToken());

values.put(UserInfo.TOKENSECRET, user.getTokenSecret());

Long uid = db.insert(SqliteHelper.TB_NAME, UserInfo.ID, values);

Log.e(“SaveUserInfo”,uid+“”);

return uid;

}

//删除users表的记录

public int DelUserInfo(String UserId){

int id= db.delete(SqliteHelper.TB_NAME, UserInfo.USERID +“=”+UserId, null);

Log.e(“DelUserInfo”,id+“”);

return id;

}

}

完成上面的代码后,我们需要在载入页面中调用上面的方法实现sqlite库中是否已经保存有用户的新浪微博的UserID号、Access Token、Access Secret的记录的功能在MainActivity的onCreate方法添加代码:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//获取账号列表

dbHelper=new DataHelper(this);

List userList= dbHelper.GetUserList(true);

if(userList.isEmpty())//如果为空说明第一次使用跳到AuthorizeActivity页面进行OAuth认证

{

Intent intent = new Intent();

intent.setClass(MainActivity.this, AuthorizeActivity.class);

startActivity(intent);

}

else//如果不为空读取这些记录的UserID号、Access Token、Access Secret值

//然后根据这3个值调用新浪的api接口获取这些记录对应的用户昵称和用户头像图标等信息。

{

for(UserInfo user:userList){

}

}

}

本篇说说关于OAuth授权认证的事情,新浪开放api都必须在这个基础上才能调用,所以有必要专门来讲讲,前面的文章中已经提到过关于新浪微博提供了OAuth和Base OAuth两种认证方式,并且本项目采用OAuth认证方式,至于为什么采用这个OAuth认证而不采用Base OAuth认证原因很简单,自从Twitter只支持OAuth认证方式以来,各大应用都纷纷转向OAuth认证方式,而新浪微博的开放平台也将在近日停止Base OAuth的认证方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (30.41 KB)

OAuth的基本概念,OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同样新浪微博提供OAuth认证也是为了保证用户账号和密码的安全,在这里通过OAuth建立普通新浪微博用户、客户端程序(我们正在开发的这个android客户端程序)、新浪微博三者之间的相互信任关系,让客户端程序(我们正在开发的这个android客户端程序)不需要知道用户的账号和密码也能浏览、发布微博,这样有效的保护了用户账号的安全性不需要把账号密码透露给客户端程序又达到了通过客户端程序写微博看微博目的。这个是OAuth的作用。

结合新浪微博的OAuth认证来说说具体的功能实现,首先罗列一下关键字组,下面四组关键字跟我们接下来OAuth认证有非常大的关系。

第一组:(App Key和App Secret),这组参数就是本系列文本第一篇提到的建一个新的应用获取App Key和App Secret。

第二组:(Request Token和Request Secret)

第三组:(oauth_verifier)

第四组:(user_id、Access Token和Access Secret)

新浪微博的OAuth认证过程,当用户第一次使用本客户端软件时,客户端程序用第一组作为参数向新浪微博发起请求,然后新浪微博经过验证后返回第二组参数给客户端软件同时表示新浪微博信任本客户端软件,当客户端软件获取第二组参数时作为参数引导用户浏览器跳至新浪微博的授权页面,然后用户在新浪的这个授权页面里输入自己的微博账号和密码进行授权,完成授权后根据客户端设定的回调地址把第三组参数返回给客户端软件并表示用户也信任本客户端软件,接下客户端软件把第二组参数和第三组参数作为参数再次向新浪微博发起请求,然后新浪微博返回第四组参数给客户端软件,第四组参数需要好好的保存起来这个就是用来代替用户的新浪账号和密码用的,在后面调用api时都需要。从这个过程来看用户只是在新浪微博的认证网页输入过账户和密码并没有在客户端软件里输入过账户和密码,客户端软件只保存了第四组数据并没有保存用户的账户和密码,这样有效的避免了账户和密码透露给新浪微博之外的第三方应用程序,保证 了安全性。

本项目用为了方便开发采用了oauth-signpost开源项目进行OAuth认证开发,新建OAuth.java类文件对OA进行简单的封装,OAuth类主要有RequestAccessToken、GetAccessToken、SignRequest三个方法,第一个方法RequestAccessToken就是上面过程中用来获取第三组参数用的,GetAccessToken方法是用来获取第四组参数用,SignRequest方法是用来调用api用。由于采用了oauth-signpost开源项目简单了很多。具体代码如下:

public class OAuth {

private CommonsHttpOAuthConsumer httpOauthConsumer;

private OAuthProvider httpOauthprovider;

public String consumerKey;

public String consumerSecret;

public OAuth()

{

// 第一组:(App Key和App Secret)

// 这组参数就是本系列文本第一篇提到的建一个新的应用获取App Key和App Secret。

this(“3315495489”,“e2731e7grf592c0fd7fea32406f86e1b”);

}

public OAuth(String consumerKey,String consumerSecret)

{

this.consumerKey=consumerKey;

this.consumerSecret=consumerSecret;

}

public Boolean RequestAccessToken(Activity activity,String callBackUrl){

Boolean ret=false;

try{

httpOauthConsumer = new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);

httpOauthprovider = new DefaultOAuthProvider(“http://api.t.sina.com.cn/oauth/request_token”,“http://api.t.sina.com.cn/oauth/access_token”,“http://api.t.sina.com.cn/oauth/authorize”);

String authUrl = httpOauthprovider.retrieveRequestToken(httpOauthConsumer, callBackUrl);

activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));

ret=true;

}catch(Exception e){

}

return ret;

}

public UserInfo GetAccessToken(Intent intent){

UserInfo user=null;

Uri uri = intent.getData();

String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);

try {

httpOauthprovider.setOAuth10a(true);

httpOauthprovider.retrieveAccessToken(httpOauthConsumer,verifier);

} catch (OAuthMessageSignerException ex) {

ex.printStackTrace();

} catch (OAuthNotAuthorizedException ex) {

ex.printStackTrace();

} catch (OAuthExpectationFailedException ex) {

ex.printStackTrace();

} catch (OAuthCommunicationException ex) {

ex.printStackTrace();

}

SortedSet user_id= httpOauthprovider.getResponseParameters().get(“user_id”);

String userId=user_id.first();

String userKey = httpOauthConsumer.getToken();

String userSecret = httpOauthConsumer.getTokenSecret();

user=new UserInfo();

user.setUserId(userId);

user.setToken(userKey);

user.setTokenSecret(userSecret);

return user;

}

public HttpResponse SignRequest(String token,String tokenSecret,String url,List params)

{

HttpPost post = new HttpPost(url);

//HttpClient httpClient = null;

try{

post.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

//关闭Expect:100-Continue握手

//100-Continue握手需谨慎使用,因为遇到不支持HTTP/1.1协议的服务器或者代理时会引起问题

post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);

return SignRequest(token,tokenSecret,post);

}

public HttpResponse SignRequest(String token,String tokenSecret,HttpPost post){

httpOauthConsumer = new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);

httpOauthConsumer.setTokenWithSecret(token,tokenSecret);

HttpResponse response = null;

try {

httpOauthConsumer.sign(post);

} catch (OAuthMessageSignerException e) {

e.printStackTrace();

} catch (OAuthExpectationFailedException e) {

e.printStackTrace();

} catch (OAuthCommunicationException e) {

e.printStackTrace();

}

//取得HTTP response

try {

response = new DefaultHttpClient().execute(post);

} catch (ClientProtocolException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return response;

}

}

这样就完成了OAuth功能类的开发,后面都会用到这个类相关的方法。本篇到这里就算是完结请继续关注后面的文章。

上一篇讲了讲OAuth授权认证的事情,大概的介绍了OAuth的原理,并且完成了一个OAuth.java的类库,提供了几个OAuth认证必要的方法,本篇开始具体讲本项目的用户授权功能,用户授权页面是当用户第一次使用本软件的时候自动从载入页面跳转过来的显示的页面,涉及OAuth认证相关都是在上一篇的OAuth.java的类基础上开发。用户授权页面分为UI篇和功能篇两篇,本篇先来讲讲UI的实现,这次就不贴PS的效果图了直接贴实现后的功能截图如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (84.47 KB)

看上面的图,其实这个页面的UI实现不复杂,首先是背景部分的实现这个参考 android开发我的新浪微博客户端-载入页面UI篇(1.1),重点来讲讲这个半透明的弹出对话框窗口是如何实现的,首先新建名为AuthorizeActivity.java的Activity,并且在AndroidManifest.xml文件中添加这个Activity,这样这个Activity才能被使用,接下来为这个Activity新建名为authorize.xml的Layout,这个Layout很简单只负责logo小图标显示,背景部分和透明窗口都是有代码来实现,所以非常简单参考 android开发我的新浪微博客户端-载入页面UI篇(1.1)。

完成Layout建立后在AuthorizeActivity的onCreate方法添加如下代码,设置authorize.xml为AuthorizeActivity的页面Layout:

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.authorize);

}

接下来是本文的重点部分,半透明弹窗用Dialog控件进行实现,首先为这个半透明弹窗新建一个名为dialog.xml的Layout,这个Layout主要是对4个元素进行布局,如图所示分别为i小图标、信息提示、中间文字、开始按钮,首先用LinearLayout对i小图标和信息提示进行水平布局,中间文字以一个TextView跟在下面,对于开始按钮是用RelativeLayout进行底部对齐显示。具体代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:padding=“10dip”>

<LinearLayout

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“horizontal”>

<ImageView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:src=“@drawable/info_icon”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“信息提示”

android:textSize=“13px”

android:textColor=“#219ac6”

android:layout_marginLeft=“5dip”>

<TextView

android:id=“@+id/text_info”

android:layout_marginTop=“6px”

android:layout_width=“200px”

android:layout_height=“wrap_content”

android:textColor=“#686767”

android:textSize=“14px”

android:text=“第一次使用需要输入您的新浪微博账号和密码进行登录授权”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“40px”>

<LinearLayout

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“horizontal”

android:layout_centerHorizontal=“true”

android:layout_alignParentBottom=“true”>

<ImageButton

android:id=“@+id/btn_start”

android:layout_width=“80px”

android:layout_height=“31px”

android:src=“@drawable/btn_start_selector”>

<ImageButton

android:id=“@+id/btn_cancel”

android:layout_width=“80px”

android:layout_height=“31px”

android:layout_marginLeft=“8px”

android:src=“@drawable/btn_cancel_selector”>

完成了半透明弹窗的Layout定义接下来我们要做的就是为它写一个自定义样式来实现我们想要的显示效果,首先我们需准备一个圆角的半透明png图片名为dia_bg.png并且添加到drawable中,接下来再res/values文件夹新建名为 dialogStyle.xml的resources样式文件,具体代码如下:

<?xml version="1.0" encoding="utf-8"?>

<mce:style name=“dialog” parent=“@android:style/Theme.Dialog”><!–

@null

true

false

true

@drawable/dia_bg

false

–></mce:style><style name=“dialog” parent=“@android:style/Theme.Dialog” mce_bogus=“1”>@null

true

false

true

@drawable/dia_bg

false

这个样式文件的说明如下

parent=“@android:style/Theme.Dialog” :在系统Dialog样式基础上,相当于继承系统样式

@null :Dialog的windowFrame框为无

true:是否浮现在activity之上

false:是否半透明

true:是否显示title

@drawable/dia_bg:设置dialog的背景

false: 背景是否模糊显示

接下来写java代码把这个半透明弹窗显示出来,在AuthorizeActivity的onCreate方法添加如下代码:

View diaView=View.inflate(this, R.layout.dialog, null);

dialog=new Dialog(AuthorizeActivity.this,R.style.dialog);

dialog.setContentView(diaView);

dialog.show();

最后运行查看效果,到这里我们的任务已经完成了。请关注下一篇功能篇。

android开发我的新浪微博客户端-用户授权页面功能篇(3.2)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (30.41 KB)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (84.47 KB)

在上一篇实现了用户授权页面的UI,如上图,接下来要做的就是在这个基础上完成功能部分真正实现用户的授权认证,这一篇是android开发我的新浪微博客户端-OAuth篇(2.1)的具体应用篇原理就不多解释了不懂的看OAuth篇即可。认证过程从点击开始按钮然后跳转到新浪的授权页面,接着用户在新浪的页面里输入自己的账户和密码确定后返回用户授权页面。首先给开始按钮添加点击事件代码,代码中主要是调用我们前面android开发我的新浪微博客户端-OAuth篇(2.1)完成的OAuth类的RequestAccessToken方法用来获取oauth_verifier,具体代码如下:

ImageButton stratBtn=(ImageButton)diaView.findViewById(R.id.btn_start);

stratBtn.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View arg0) {

auth=new OAuth();

auth.RequestAccessToken(AuthorizeActivity.this, CallBackUrl);

}

});

上面的代码中重点来说明一下 RequestAccessToken方法的第二参数CallBackUrl,这个参数是用户在新浪的页面中输入账户密码后完成认证后返回的地址,我这里是这样设置的CallBackUrl = “myapp://AuthorizeActivity”,在AndroidManifest.xml中配置给AuthorizeActivity添加如下配置把myapp://AuthorizeActivity指向到AuthorizeActivity,这样当页面返回到AuthorizeActivity中就可以获取到传过来的oauth_verifier参数。

再AuthorizeActivity如果来接收返回的oauth_verifier参数呢?接下来在AuthorizeActivity添加如下方法:
@Override

protected void onNewIntent(Intent intent) {

super.onNewIntent(intent);

//在这里处理获取返回的oauth_verifier参数

}

关于onNewIntent的说明是这样的,onCreate是用来创建一个Activity也就是创建一个窗体,但一个Activty处于任务栈的顶端,若再次调用startActivity去创建它,则不会再次创建。若你想利用已有的Acivity去处理别的Intent时,你就可以利用onNewIntent来处理。在onNewIntent里面就会获得新的Intent,在这里AuthorizeActivity是属于已有的Acivity,所以需要onNewIntent来处理接收返回的参数,获取oauth_verifier参数后OAuth还没有结束从android开发我的新浪微博客户端-OAuth篇(2.1)描述来看还需要进行根据这个参数继续向新浪微博请求获取User_id、Access Token和Access Secret,在这里我把这些操作全部写在了GetAccessToken方法中。在onNewIntent添加如下代码:

UserInfo user= auth.GetAccessToken(intent);

if(user!=null){

DataHelper helper=new DataHelper(this);

String uid=user.getUserId();

if(helper.HaveUserInfo(uid))

{

helper.UpdateUserInfo(user);

Log.e(“UserInfo”, “update”);

}else

{

helper.SaveUserInfo(user);

Log.e(“UserInfo”, “add”);

}

}

通过上面的代码完成了User_id、Access Token和Access Secret 获取并且保存到了sqlite库中,这样就完成了用户的OAuth认证,当需要调用新浪的api时只需要去sqlite库中找该用户的User_id、Access Token和Access Secret 即可。到这里本篇就结束了,请关注下一篇。

android开发我的新浪微博客户端-登录页面UI篇(4.1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (83.17 KB)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (85.15 KB)

首先回顾一下功能流程当用户开启软件显示载入页面时程序首先去sqlite库查询是否已经保存有用户的新浪微博的UserID号、Access Token、Access Secret的记录如果没有一条记录那么跳转到用户授权功能页面,这个已经由上面两篇文章实现了,如果有记录那么页面跳转到用户登录页面,也就是本篇以及下篇要实现的功能,本篇讲UI的实现,本项目支持多微博账号了,也就是用户可以设置多个微博账号,登录的时候选择其中的一个登录,具体效果如上图,新建名LoginActivity.java的Activity并且在AndroidManifest.xml中进行相应配置,这个页面就是我们要实现的用户登录页面。

看上面的效果,首先页面分3部分实现,背景部分、底部菜单部分、用户选择以及头像显示部分,首先在res/layout的目录下新建名为login.xml的layout,然后根据页面显示要求编写如下的布局控制:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:id=“@+id/layout”

android:orientation=“vertical”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<ImageView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:src=“@drawable/logo_s”

android:layout_marginTop=“5dip”

android:layout_marginLeft=“5dip”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<RelativeLayout

android:id=“@+id/iconBtn”

android:layout_width=“90px”

android:layout_height=“80px”

android:background=“@drawable/icon_selector”

android:layout_above=“@+id/selectLayout”

android:layout_centerHorizontal=“true”

android:layout_marginBottom=“20dip”>

<ImageView

android:id=“@+id/icon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”>

<RelativeLayout

android:id=“@+id/selectLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”>

<EditText

android:id=“@+id/iconSelect”

android:layout_width=“200px”

android:layout_height=“wrap_content”

android:maxLength=“10”

android:paddingLeft=“20px”

android:editable=“false”

android:enabled=“false”

android:textSize=“13px”

android:background=“@drawable/input_over” >

<ImageButton

android:id=“@+id/iconSelectBtn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginRight=“1.0dip”

android:layout_alignTop=“@+id/iconSelect”

android:layout_alignRight=“@+id/iconSelect”

android:layout_alignBottom=“@+id/iconSelect”

android:background=“@drawable/more_selector” >

<ImageButton

android:id=“@+id/login”

android:layout_width=“40px”

android:layout_height=“40px”

android:layout_marginLeft=“5dip”

android:layout_alignTop=“@+id/iconSelectBtn”

android:layout_toRightOf=“@+id/iconSelectBtn”

android:layout_alignBottom=“@+id/iconSelectBtn”

android:background=“@drawable/btn_in_selector” >

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“44dip”

android:layout_alignParentBottom=“true”

android:background=“#BB768e95”>

<LinearLayout

android:id=“@+id/addLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:layout_alignParentLeft=“true”

android:gravity=“center”

android:layout_marginTop=“3px”>

<ImageButton

android:id=“@+id/addIcon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:background=“@drawable/add_selector”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#ffffff”

android:textSize=“12px”

android:text=“添加账号”>

<LinearLayout

android:id=“@+id/exitLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:layout_centerInParent=“true”

android:gravity=“center”

android:layout_marginTop=“3px”>

<ImageButton

android:id=“@+id/exitIcon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:background=“@drawable/exit_selector”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#ffffff”

android:textSize=“12px”

android:text=“退出软件”>

<LinearLayout

android:id=“@+id/delLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:layout_alignParentRight=“true”

android:gravity=“center”

android:layout_marginTop=“3px”>

<ImageButton

android:id=“@+id/delIcon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:background=“@drawable/del_selector”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#ffffff”

android:textSize=“12px”

android:text=“删除账号”>

正对上面的login.xml的layout进行一下说明,背景部分前面已经讲过了这里也就不重复。
  底部菜单实现,原本我是采用GridView实现的非常的方便但是后来由于显示位置不好控制改成了用RelativeLayout和LinearLayout嵌套的方式,实现的比较土但是达到了显示需求,首先是一个最外面的RelativeLayout目的是用来实现底部对齐显示,并且把这个RelativeLayout的背景设置为浅蓝色半透明的效果,关键这2行:android:layout_alignParentBottom=“true"和android:background=”#BB768e95"。然后是在RelativeLayout内部添加3个LinearLayout分别是用来显示添加账号、退出软件、删除账号3个功能按钮菜单,并且分别设置为左对齐、居中对齐、右对齐,3个LinearLayout都设置为垂直布局androidrientation=“vertical”,然后每LinearLayout添加相应的图片和文字。
  用户选择以及头像显示部分,这块分成3小块,用来显示用户头像的ImageView、用来显示用户名字并且点击可以出现选择列表的EditText、用来点击进入当前选择用户首页的功能按钮ImageButton,这3小块的布局实现也是采用elativeLayout和LinearLayout相互嵌套配合的方式实现的具体参考login.xml。这里重点说说这个账号选择列表弹出窗口的实现,当点击下拉箭头按钮的时候弹出并显示,这个是用Dialog控件实现,首先准备好圆角的半透明背景图mask_bg.png然后添加到res/drawable-mdpi文件夹下,接着自定义一个Dialog样式文件,在res/values目录下新建名为dialogStyles2.xml的resources文件,在用户授权验证页面的时候我们也自定义过类似的Dialog的样式,具体解释可以参考前面的户授权验证页面功能,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<mce:style name=“dialog2” parent=“@android:style/Theme.Dialog”><!–

@null

true

false

true

@drawable/mask_bg

true

–></mce:style><style name=“dialog2” parent=“@android:style/Theme.Dialog” mce_bogus=“1”>@null

true

false

true

@drawable/mask_bg

true

接下来还需要定义选择列表的layout,新建名为dialog2.xml的layout文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:padding=“4dip”>

<ListView

android:id=“@+id/list”

android:layout_width=“240px”

android:layout_height=“220px”

android:divider=“#f1f2f2”

android:dividerHeight=“1px”

android:layout_margin=“5px”

android:background=“#ffffff”

android:cacheColorHint=“#00000000”>

完成了layout和样式文件的编写,接下来就是把dialogStyles2.xml样式文件和dialog2.xml的列表layout用起来,当点击id为iconSelectBtn的ImageButton时显示用户选择窗口,在LoginActivity的onCreate方法中添加如下代码:
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.login);

LinearLayout layout=(LinearLayout)findViewById(R.id.layout);

//背景自动适应

AndroidHelper.AutoBackground(this, layout, R.drawable.bg_v, R.drawable.bg_h);

ImageButton iconSelectBtn=(ImageButton)findViewById(R.id.iconSelectBtn);

iconSelectBtn.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View v) {

View diaView=View.inflate(LoginActivity.this, R.layout.dialog2, null);

dialog=new Dialog(LoginActivity.this,R.style.dialog2);

dialog.setContentView(diaView);

dialog.show();

}

});

到这里登录的UI部分就实现的差不多了,剩下的都是一些功能部分代码用来实现从sqlite中账号列表的获取,以及点击选择等交互操作等,这些在下一篇中来继续的讲。

android开发我的新浪微博客户端-登录页面功能篇(4.2)

上一篇中完成了如上图的UI部分的实现,现在继续来讲功能的实现,用户登录操作主要就是账号列表显示和选择账号登录两个功能其他的都是些简单的辅助功能,首先是点击id为iconSelectBtn的ImageButton时显示用户选择窗口,这个时候去数据库中获取账号记录然后在选择窗口中以列表方式显示出来,通过上一篇已经知道Id为list的ListView控件来显示账号列表,首先是从数据库中获取所有的账户记录然后设置默认选中的用户账号代码如下:
private void initUser(){

//获取账号列表

dbHelper=new DataHelper(this);

userList = dbHelper.GetUserList(false);

if(userList.isEmpty())

{

Intent intent = new Intent();

intent.setClass(LoginActivity.this, AuthorizeActivity.class);

startActivity(intent);

}

else

{

SharedPreferences preferences = getSharedPreferences(Select_Name, Activity.MODE_PRIVATE);

String str= preferences.getString(“name”, “”);

UserInfo user=null;

if(str!=“”)

{

user=GetUserByName(str);

}

if(user==null)

{

user=userList.get(0);

}

icon.setImageDrawable(user.getUserIcon());

iconSelect.setText(user.getUserName());

}

}

这个initUser() 初始账号的方法在LoginActivity的onCreate中调用,主要完成两件事情,第一件获取通过userList = dbHelper.GetUserList(false);获取所有的账户记录,关于DataHelper前面已经有说过了,如果获取的用户记录为空那么就跳转到用户授权功能页面让用户添加账号,如果不为空那么通过SharedPreferences去读取用户上一次选择的账号名称,如果没有或者数据库里账号记录不包括这个账户名称那么默认显示记录的第一个账号和头像,如果有那么显示这个账户的名称和头像。关于SharedPreferences,是android提供给开发者用来存储一些简单的数据用的,非常方便类似于网站的Cookie,在这里我就是用这个来保存上一次用户选择的是哪个账号,非常实用。
     接下类首先为Id为list的ListView控件准备数据Adapter,这个Adapter非常简单就是普通的adapter继承BaseAdapter即可,代码如下:
public class UserAdapater extends BaseAdapter{

@Override

public int getCount() {

return userList.size();

}

@Override

public Object getItem(int position) {

return userList.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_user, null);

ImageView iv = (ImageView) convertView.findViewById(R.id.iconImg);

TextView tv = (TextView) convertView.findViewById(R.id.showName);

UserInfo user = userList.get(position);

try {

//设置图片显示

iv.setImageDrawable(user.getUserIcon());

//设置信息

tv.setText(user.getUserName());

} catch (Exception e) {

e.printStackTrace();

}

return convertView;

}

接下就是为这个ListView设定数据源Adapter,在账号选择窗口显示的时候进行设置,添加到id为iconSelectBtn的ImageButton的OnClickListener中代码如下:
ImageButton iconSelectBtn=(ImageButton)findViewById(R.id.iconSelectBtn);

iconSelectBtn.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View v) {

dialog.show();

UserAdapater adapater = new UserAdapater();

ListView listview=(ListView)diaView.findViewById(R.id.list);

listview.setVerticalScrollBarEnabled(false);// ListView去掉下拉条

listview.setAdapter(adapater);

listview.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(AdapterView<?> arg0, View view,int arg2, long arg3) {

TextView tv=(TextView)view.findViewById(R.id.showName);

iconSelect.setText(tv.getText());

ImageView iv=(ImageView)view.findViewById(R.id.iconImg);

icon.setImageDrawable(iv.getDrawable());

dialog.dismiss();

}

});

}

});

通过上面代码完成了账号选择的功能,接下来给id为login的ImageButton添加OnClickListener,使得点击后以当前选择账号进入微博首页,代码如下:
@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.login);

ImageButton login=(ImageButton)findViewById(R.id.login);

login.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View v) {

GoHome();

}

});

}

//进入用户首页

private void GoHome(){

if(userList!=null)

{

String name=iconSelect.getText().toString();

UserInfo u=GetUserByName(name);

if(u!=null)

{

ConfigHelper.nowUser=u;//获取当前选择的用户并且保存

}

}

if(ConfigHelper.nowUser!=null)

{

//进入用户首页

Intent intent = new Intent();

intent.setClass(LoginActivity.this, HomeActivity.class);

startActivity(intent);

}

}

在上面的GoHome方法中ConfigHelper.nowUser是类型为UserInfo的static类型用来保存当前登录账号的信息,替代web中session使用。
最后添加如下方法,用来当这个登录LoginActivity结束的时候保存当前选择的账户名称到SharedPreferences中,以便帮用户记住登录账号的功能,就是前面的initUser() 初始账号的方法中会获取保存在SharedPreferences中的账户名称,代码如下:
@Override

protected void onStop() {

//获得SharedPreferences对象

SharedPreferences MyPreferences = getSharedPreferences(Select_Name, Activity.MODE_PRIVATE);

//获得SharedPreferences.Editor对象

SharedPreferences.Editor editor = MyPreferences.edit();

//保存组件中的值

editor.putString(“name”, iconSelect.getText().toString());

editor.commit();

super.onStop();

}

至此登录页面功能篇结束,请继续关注下一篇。

android开发我的新浪微博客户端-用户首页面UI篇(5.1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (101.43 KB)

在前篇完成了用户登录功能后开始用户首页的开发,用户的首页主要的内容是当前登录用户关注的微博列表,本篇先来讲讲UI的实现,效果如上图,整个页面分为上、中、下三部分,上面部分是工具条,显示当前登录用户的昵称以及写微博、刷新两个功能按钮;中间部分是当前用户关注的最新微博列表,下面部分是功能切换栏,用来进行各个功能之间的切换。

首先新建名为HomeActivity.java的Activity作为用户首页,然后在res/layout目录下新建名为home.xml的Layout,具体代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:id=“@+id/layout”

android:orientation=“vertical”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:layout_margin=“3px”>

<ImageView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:src=“@drawable/logo_ss”>

<TextView

android:id=“@+id/showName”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”

android:textColor=“#343434”

android:textSize=“15px”>

<ImageButton

android:id=“@+id/writeBtn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_toLeftOf=“@+id/refreshBtn”

android:background=“@drawable/btn_write_selector”>

<ImageButton

android:id=“@+id/refreshBtn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_alignParentRight=“true”

android:layout_marginLeft=“12px”

android:background=“@drawable/btn_refresh_selector”>

<LinearLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:background=“@drawable/hr”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<ListView

android:id=“@+id/Msglist”

android:layout_width=“fill_parent”

android:layout_height=“match_parent”

android:divider=“@drawable/divider”

android:dividerHeight=“2px”

android:layout_margin=“0px”

android:background=“#BBFFFFFF”

android:cacheColorHint=“#00000000”

android:layout_above=“@+id/toolbarLayout”

android:fastScrollEnabled=“true”

android:focusable=“true”>

<LinearLayout

android:id=“@+id/loadingLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:visibility=“invisible”

android:layout_centerInParent=“true”>

<ProgressBar

android:id=“@+id/loading”

android:layout_width=“31px”

android:layout_height=“31px”

android:layout_gravity=“center”

style=“@style/progressStyle”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“正在载入”

android:textSize=“12px”

android:textColor=“#9c9c9c”

android:layout_gravity=“center”

android:layout_below=“@+id/loading”>

<LinearLayout

android:id=“@+id/toolbarLayout”

android:layout_width=“fill_parent”

android:layout_height=“44dip”

android:layout_alignParentBottom=“true”>

 

这个布局首先是一个竖直的根LinearLayout,在这个根LinearLayout里面分别是两个RelativeLayout, 第一个RelativeLayout 用来显示页面的工具条,第二个RelativeLayout用来显示列表以及底部的功能栏,特别主要在这第二个RelativeLayout中有一个id为loadingLayout的LinearLayout是用来显示数据载入中的动画,它的android:visibility属性为invisible(也可以设置成gone,区别:invisible这个View在ViewGroupt中仍保留它的位置,不重新layout
gone>不可见,但这个View在ViewGroupt中不保留位置,重新layout,那后面的view就会取代他的位置。 ),也就是一开始不显示的意思,接下来看看
<ProgressBar

android:id=“@+id/loading”
        android:layout_width=“31px”
        android:layout_height=“31px”

android:layout_gravity=“center”

style=“@style/progressStyle”>

      这个ProgressBar控件就是用来显示动画用的,关键就是 style=“@style/progressStyle”,在res/values目录下新建名为loadingstyles.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<mce:style name=“progressStyle” width=“38” height=“38” parent=“@android:style/Widget.ProgressBar.Small”><!–

@anim/loading

–></mce:style><style name=“progressStyle” width=“38” height=“38” parent=“@android:style/Widget.ProgressBar.Small” mce_bogus=“1”>@anim/loading

 

接着准备好r1.png - r8.png,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (998 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (980 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (1013 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (1014 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (986 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (992 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (1010 Bytes)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (1 KB)

八张不同的小图片分别代表每旋转45度图片,八张刚好是360度。把这些图片添加到res/drawable-mdpi目录中。然后在res/anim目录下新建名为loading.xml动画文件,内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<animation-list android:oneshot=“false”

xmlns:android=“http://schemas.android.com/apk/res/android”>

 

关于Android播放动画实现我是参考http://www.eoeandroid.com/forum.php?mod=viewthread&tid=67311&extra=
    本篇到这里就结束了,下一篇继续讲用户首页的功能实现,请关注。

android开发我的新浪微博客户端-用户首页面功能篇(5.2)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (101.43 KB)

上一篇完成用户首页的UI实现,本篇接下来讲功能部分的实现,本页面主要的功能就用户关注的最新微博列表,从上一篇中知道本列表是用ID为Msglist的ListView控件来实现,本篇的主要就讲解如果获取微博列表数据给这个ListView提供显示数据。ListView每一条子数据分别由用户头像、用户昵称、发布时间、是否包含照片、微博内容这五部分组成,根据这五部分定义一个名为WeiBoInfo.java实体类,代码如下:
public class WeiBoInfo {

//文章id

private String id;

public String getId(){

return id;

}

public void setId(String id){

this.id=id;

}

//发布人id

private String userId;

public String getUserId(){

return userId;

}

public void setUserId(String userId){

this.userId=userId;

}

//发布人名字

private String userName;

public String getUserName(){

return userName;

}

public void setUserName(String userName){

this.userName=userName;

}

//发布人头像

private String userIcon;

public String getUserIcon(){

return userIcon;

}

public void setUserIcon(String userIcon){

this.userIcon=userIcon;

}

//发布时间

private String time;

public String getTime(){

return time;

}

public void setTime(String time)

{

this.time=time;

}

//是否有图片

private Boolean haveImage=false;

public Boolean getHaveImage(){

return haveImage;

}

public void setHaveImage(Boolean haveImage){

this.haveImage=haveImage;

}

//文章内容

private String text;

public String getText(){

return text;

}

public void setText(String text){

this.text=text;

}

}

然后在res/layout目录下新建名为weibo.xml的Layout用来控制ListView子项的显示部件,代码很简单不多解释了,直接看下面代码:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“horizontal”>

<ImageView

android:id=“@+id/wbicon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:src=“@drawable/usericon”

android:layout_margin=“8px”>

<LinearLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:paddingLeft=“0px”

android:paddingRight=“5px”

android:layout_marginTop=“5px”

android:layout_marginBottom=“5px”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”>

<TextView

android:id=“@+id/wbuser”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textSize=“15px”

android:textColor=“#424952”

android:layout_alignParentLeft=“true”>

<ImageView

android:id=“@+id/wbimage”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginTop=“3px”

android:layout_marginRight=“5px”

android:layout_toLeftOf=“@+id/wbtime”>

<TextView

android:id=“@+id/wbtime”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_alignParentRight=“true”

android:textColor=“#f7a200”

android:textSize=“12px”>

<TextView

android:id=“@+id/wbtext”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#424952”

android:textSize=“13px”

android:layout_marginTop=“4px”>

 

接下来为列表控件定义一个数据Adapter,代码如下:
private List wbList;

//微博列表Adapater

public class WeiBoAdapater extends BaseAdapter{

private AsyncImageLoader asyncImageLoader;

@Override

public int getCount() {

return wbList.size();

}

@Override

public Object getItem(int position) {

return wbList.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

asyncImageLoader = new AsyncImageLoader();

convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.weibo, null);

WeiBoHolder wh = new WeiBoHolder();

wh.wbicon = (ImageView) convertView.findViewById(R.id.wbicon);

wh.wbtext = (TextView) convertView.findViewById(R.id.wbtext);

wh.wbtime = (TextView) convertView.findViewById(R.id.wbtime);

wh.wbuser = (TextView) convertView.findViewById(R.id.wbuser);

wh.wbimage=(ImageView) convertView.findViewById(R.id.wbimage);

WeiBoInfo wb = wbList.get(position);

if(wb!=null){

convertView.setTag(wb.getId());

wh.wbuser.setText(wb.getUserName());

wh.wbtime.setText(wb.getTime());

wh.wbtext.setText(wb.getText(), TextView.BufferType.SPANNABLE);

textHighlight(wh.wbtext,new char[]{‘#’},new char[]{‘#’});

textHighlight(wh.wbtext,new char[]{‘@’},new char[]{‘:’,’ '});

textHighlight2(wh.wbtext,“http://”," ");

if(wb.getHaveImage()){

wh.wbimage.setImageResource(R.drawable.images);

}

Drawable cachedImage = asyncImageLoader.loadDrawable(wb.getUserIcon(),wh.wbicon, new ImageCallback(){

@Override

public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl) {

imageView.setImageDrawable(imageDrawable);

}

});

if (cachedImage == null) {

wh.wbicon.setImageResource(R.drawable.usericon);

}else{

wh.wbicon.setImageDrawable(cachedImage);

}

}

return convertView;

}

上面的这个Adapter实现没有什么特别的很普通,不过这个中使用了AsyncImageLoader的方法,这个是用来实现用户头像图标的异步载入显示,这样能提高列表显示的速度,提高用户体验,AsyncImageLoader的代码如下:
public class AsyncImageLoader {

//SoftReference是软引用,是为了更好的为了系统回收变量

private HashMap<String, SoftReference> imageCache;

public AsyncImageLoader() {

imageCache = new HashMap<String, SoftReference>();

}

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() {

public void handleMessage(Message message) {

imageCallback.imageLoaded((Drawable) message.obj, imageView,imageUrl);

}

};

//建立新一个新的线程下载图片

new Thread() {

@Override

public void run() {

Drawable drawable = loadImageFromUrl(imageUrl);

imageCache.put(imageUrl, new SoftReference(drawable));

Message message = handler.obtainMessage(0, drawable);

handler.sendMessage(message);

}

}.start();

return null;

}

public static Drawable loadImageFromUrl(String url){

URL m;

InputStream i = null;

try {

m = new URL(url);

i = (InputStream) m.getContent();

} catch (MalformedURLException e1) {

e1.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

Drawable d = Drawable.createFromStream(i, “src”);

return d;

}

//回调接口

public interface ImageCallback {

public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl);

}

}

完成上述的工作后,接下来就是显示微薄列表, 在HomeActivity的onCreate方法中调用loadList();代码如下:
@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.home);

。。。。。。

loadList();

}

private void loadList(){

if(ConfigHelper.nowUser==null)

{

}

else

{

user=ConfigHelper.nowUser;

//显示当前用户名称

TextView showName=(TextView)findViewById(R.id.showName);

showName.setText(user.getUserName());

OAuth auth=new OAuth();

String url = “http://api.t.sina.com.cn/statuses/friends_timeline.json”;

List params=new ArrayList();

params.add(new BasicNameValuePair(“source”, auth.consumerKey));

HttpResponse response =auth.SignRequest(user.getToken(), user.getTokenSecret(), url, params);

if (200 == response.getStatusLine().getStatusCode()){

try {

InputStream is = response.getEntity().getContent();

Reader reader = new BufferedReader(new InputStreamReader(is), 4000);

StringBuilder buffer = new StringBuilder((int) response.getEntity().getContentLength());

try {

char[] tmp = new char[1024];

int l;

while ((l = reader.read(tmp)) != -1) {

buffer.append(tmp, 0, l);

}

} finally {

reader.close();

}

String string = buffer.toString();

//Log.e(“json”, “rs:” + string);

response.getEntity().consumeContent();

JSONArray data=new JSONArray(string);

for(int i=0;i<data.length();i++)

{

JSONObject d=data.getJSONObject(i);

//Log.e(“json”, “rs:” + d.getString(“created_at”));

if(d!=null){

JSONObject u=d.getJSONObject(“user”);

if(d.has(“retweeted_status”)){

JSONObject r=d.getJSONObject(“retweeted_status”);

}

//微博id

String id=d.getString(“id”);

String userId=u.getString(“id”);

String userName=u.getString(“screen_name”);

String userIcon=u.getString(“profile_image_url”);

Log.e(“userIcon”, userIcon);

String time=d.getString(“created_at”);

String text=d.getString(“text”);

Boolean haveImg=false;

if(d.has(“thumbnail_pic”)){

haveImg=true;

//String thumbnail_pic=d.getString(“thumbnail_pic”);

//Log.e(“thumbnail_pic”, thumbnail_pic);

}

Date date=new Date(time);

time=ConvertTime(date);

if(wbList==null){

wbList=new ArrayList();

}

WeiBoInfo w=new WeiBoInfo();

w.setId(id);

w.setUserId(userId);

w.setUserName(userName);

w.setTime(time);

w.setText(text);

w.setHaveImage(haveImg);

w.setUserIcon(userIcon);

wbList.add(w);

}

}

}catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (JSONException e) {

e.printStackTrace();

}

}

if(wbList!=null)

{

WeiBoAdapater adapater = new WeiBoAdapater();

ListView Msglist=(ListView)findViewById(R.id.Msglist);

Msglist.setOnItemClickListener(new OnItemClickListener(){

@Override

public void onItemClick(AdapterView<?> arg0, View view,int arg2, long arg3) {

Object obj=view.getTag();

if(obj!=null){

String id=obj.toString();

Intent intent = new Intent(HomeActivity.this,ViewActivity.class);

Bundle b=new Bundle();

b.putString(“key”, id);

intent.putExtras(b);

startActivity(intent);

}

}

});

Msglist.setAdapter(adapater);

}

}

loadingLayout.setVisibility(View.GONE);

}

上面的loadList() 方法通过新浪Api接口http://api.t.sina.com.cn/statuses/friends_timeline.json获取当前登录用户及其所关注用户的最新微博消息,然后显示到列表中。
      这样就完成了用户首页功能的开发。

android开发我的新浪微博客户端-阅读微博UI篇(6.1)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (154.98 KB)

上一篇完成了微博列表的功能,本篇接着做预读微博的功能,本篇主要讲讲UI部分的实现,最终实现的效果如上图所示。整个显示页面从上往下分为四部分,第一部分顶部工具条、第二部分作者头像和名称、第三部分微博正文、第四部分功能按钮区。新建名为ViewActivity.java作为阅读微博的页面,再res/layout目录下新建名为view.xml的Layout,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android=“http://schemas.android.com/apk/res/android”

android:id=“@+id/layout”

android:orientation=“vertical”

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:layout_margin=“3px”>

<ImageView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:src=“@drawable/logo_ss”>

<TextView

android:id=“@+id/showName”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_centerInParent=“true”

android:textColor=“#343434”

android:text=“阅读微博”

android:textSize=“16px”>

<ImageButton

android:id=“@+id/returnBtn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_toLeftOf=“@+id/homeBtn”

android:background=“@drawable/bnt_return_selector”>

<ImageButton

android:id=“@+id/homeBtn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_alignParentRight=“true”

android:layout_marginLeft=“12px”

android:background=“@drawable/btn_home_selector”>

<LinearLayout

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:background=“@drawable/hr”>

<RelativeLayout

android:id=“@+id/user_bg”

android:layout_width=“fill_parent”

android:layout_height=“78px”

android:paddingTop=“8px”

android:paddingLeft=“15px”

android:background=“@drawable/u_bg_v”>

<ImageView

android:id=“@+id/user_icon”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_alignParentLeft=“true”

android:src=“@drawable/usericon”>

<TextView

android:id=“@+id/user_name”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_toRightOf=“@+id/user_icon”

android:layout_marginLeft=“10px”

android:layout_marginTop=“18px”

android:textColor=“#000000”>

<ImageView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_alignParentRight=“true”

android:layout_marginRight=“5px”

android:layout_marginTop=“10px”

android:src=“@drawable/sjjt”>

<RelativeLayout

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”>

<ScrollView

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”

android:paddingLeft=“17px”

android:paddingRight=“17px”

android:paddingBottom=“5px”

android:layout_above=“@+id/menu_layout”>

<LinearLayout

android:layout_width=“fill_parent”

android:layout_height=“fill_parent”

android:orientation=“vertical”>

<TextView

android:id=“@+id/text”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#000000”

android:textSize=“15px”>

<ImageView

android:id=“@+id/pic”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”>

<LinearLayout

android:id=“@+id/loadingLayout”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:orientation=“vertical”

android:visibility=“gone”

android:layout_centerInParent=“true”>

<ProgressBar

android:id=“@+id/loading”

android:layout_width=“31px”

android:layout_height=“31px”

android:layout_gravity=“center”

style=“@style/progressStyle”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“正在载入”

android:textSize=“12px”

android:textColor=“#9c9c9c”

android:layout_gravity=“center”

android:layout_below=“@+id/loading”>

<TableLayout

android:id=“@+id/menu_layout”

android:layout_width=“fill_parent”

android:layout_height=“wrap_content”

android:gravity=“center”

android:layout_alignParentBottom=“true”

android:layout_marginBottom=“5px”>

<TableRow

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:gravity=“center”>

<Button

android:id=“@+id/btn_gz”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#3882b8”

android:textSize=“15px”

android:text=" 关注(1231)"

android:background=“@drawable/lt_selector”>

<Button

android:id=“@+id/btn_pl”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#3882b8”

android:textSize=“15px”

android:text=" 评论(31)"

android:background=“@drawable/rt_selector”>

<TableRow

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:gravity=“center”>

<Button

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#3882b8”

android:textSize=“15px”

android:layout_gravity=“left”

android:text=“刷新”

android:background=“@drawable/lb_selector”>

<Button

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:textColor=“#3882b8”

android:textSize=“15px”

android:text=“收藏”

android:background=“@drawable/rb_selector”>

 

上面这个布局实现起来并不复杂, 主要看看功能按钮区的4个按钮的点击上去的切换背景的效果,以关注按钮为例子看这行设置,android:background=“@drawable/lt_selector”,在res/drawable-mdpi目录下新建名为lt_selector.xml用来实现点击上去切换图片的效果,具体代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<item android:state_focused=“false” android:state_selected=“false” android:state_pressed=“false” android:drawable=“@drawable/tbtn_1” />

<item android:state_pressed=“true” android:drawable=“@drawable/tbtn_h_1” />

 

本篇虽然看layout文件非常的长,其实仔细看看非常的简单了没有什么难和复杂的了,就是按照前面的经验控制好图片以及控件的显示位置和样式即可,本篇中用了一个ScrollView控件这个是前面没有用到过的,主要是用来当微博的内容超出显示区域的时候出现滚动条用的这个非常容易使用,所以就简单写一下到此结束了,请继续关注下一篇阅读微博的功能篇。

android开发我的新浪微博客户端-阅读微博功能篇(6.2)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6 天前 上传

下载附件 (154.98 KB)

注:最近由于OAuth上传图片碰到了难题,一直在做这方面的研究导致博客很久没有更新。

在上面一篇中已经实现了预读微博的UI界面,效果如上图,接下来完成功能部分的代码,当用户在上一个列表界面的列表中点击某一条微博的时候显示这个阅读微博的界面,在这个界面中根据传来的微博ID,然后根据这个ID通过api获取微博的具体内容进行显示。

在ViewActivity.class的onCreate方法中添加如下代码:

private UserInfo user;

private String key=“”;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.view);

。。。。。

//获取上一个页面传递过来的key,key为某一条微博的id

Intent i=this.getIntent();

if(!i.equals(null)){

Bundle b=i.getExtras();

if(b!=null){

if(b.containsKey(“key”)){

key = b.getString(“key”);

view(key);

}

}

}

}

接下来就是view方法具体获取微博内容的方法,在这个方法中如果获取的本条微博如果包含图片那么就用前面AsyncImageLoader的方法异步载入图片并且进行显示,同时在这个方法中还要获取本条微博被转发的次数以及评论的次数,具体代码如下:
private void view(String id){

user=ConfigHelper.nowUser;

OAuth auth=new OAuth();

String url = “http://api.t.sina.com.cn/statuses/show/:id.json”;

List params=new ArrayList();

params.add(new BasicNameValuePair(“source”, auth.consumerKey));

params.add(new BasicNameValuePair(“id”, id));

HttpResponse response =auth.SignRequest(user.getToken(), user.getTokenSecret(), url, params);

if (200 == response.getStatusLine().getStatusCode()){

try {

InputStream is = response.getEntity().getContent();

Reader reader = new BufferedReader(new InputStreamReader(is), 4000);

StringBuilder buffer = new StringBuilder((int) response.getEntity().getContentLength());

try {

char[] tmp = new char[1024];

int l;

while ((l = reader.read(tmp)) != -1) {

buffer.append(tmp, 0, l);

}

} finally {

reader.close();

}

String string = buffer.toString();

//Log.e(“json”, “rs:” + string);

response.getEntity().consumeContent();

JSONObject data=new JSONObject(string);

if(data!=null){

JSONObject u=data.getJSONObject(“user”);

String userName=u.getString(“screen_name”);

String userIcon=u.getString(“profile_image_url”);

Log.e(“userIcon”, userIcon);

String time=data.getString(“created_at”);

String text=data.getString(“text”);

TextView utv=(TextView)findViewById(R.id.user_name);

utv.setText(userName);

TextView ttv=(TextView)findViewById(R.id.text);

ttv.setText(text);

ImageView iv=(ImageView)findViewById(R.id.user_icon);

AsyncImageLoader asyncImageLoader = new AsyncImageLoader();

Drawable cachedImage = asyncImageLoader.loadDrawable(userIcon,iv, new ImageCallback(){

@Override

public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl) {

imageView.setImageDrawable(imageDrawable);

}

});

if (cachedImage == null)

{

iv.setImageResource(R.drawable.usericon);

}

else

{

iv.setImageDrawable(cachedImage);

}

if(data.has(“bmiddle_pic”)){

String picurl=data.getString(“bmiddle_pic”);

String picurl2=data.getString(“original_pic”);

ImageView pic=(ImageView)findViewById(R.id.pic);

pic.setTag(picurl2);

pic.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Object obj=v.getTag();

Intent intent = new Intent(ViewActivity.this,ImageActivity.class);

Bundle b=new Bundle();

b.putString(“url”, obj.toString());

intent.putExtras(b);

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

eate(savedInstanceState);

setContentView(R.layout.view);

。。。。。

//获取上一个页面传递过来的key,key为某一条微博的id

Intent i=this.getIntent();

if(!i.equals(null)){

Bundle b=i.getExtras();

if(b!=null){

if(b.containsKey(“key”)){

key = b.getString(“key”);

view(key);

}

}

}

}

接下来就是view方法具体获取微博内容的方法,在这个方法中如果获取的本条微博如果包含图片那么就用前面AsyncImageLoader的方法异步载入图片并且进行显示,同时在这个方法中还要获取本条微博被转发的次数以及评论的次数,具体代码如下:
private void view(String id){

user=ConfigHelper.nowUser;

OAuth auth=new OAuth();

String url = “http://api.t.sina.com.cn/statuses/show/:id.json”;

List params=new ArrayList();

params.add(new BasicNameValuePair(“source”, auth.consumerKey));

params.add(new BasicNameValuePair(“id”, id));

HttpResponse response =auth.SignRequest(user.getToken(), user.getTokenSecret(), url, params);

if (200 == response.getStatusLine().getStatusCode()){

try {

InputStream is = response.getEntity().getContent();

Reader reader = new BufferedReader(new InputStreamReader(is), 4000);

StringBuilder buffer = new StringBuilder((int) response.getEntity().getContentLength());

try {

char[] tmp = new char[1024];

int l;

while ((l = reader.read(tmp)) != -1) {

buffer.append(tmp, 0, l);

}

} finally {

reader.close();

}

String string = buffer.toString();

//Log.e(“json”, “rs:” + string);

response.getEntity().consumeContent();

JSONObject data=new JSONObject(string);

if(data!=null){

JSONObject u=data.getJSONObject(“user”);

String userName=u.getString(“screen_name”);

String userIcon=u.getString(“profile_image_url”);

Log.e(“userIcon”, userIcon);

String time=data.getString(“created_at”);

String text=data.getString(“text”);

TextView utv=(TextView)findViewById(R.id.user_name);

utv.setText(userName);

TextView ttv=(TextView)findViewById(R.id.text);

ttv.setText(text);

ImageView iv=(ImageView)findViewById(R.id.user_icon);

AsyncImageLoader asyncImageLoader = new AsyncImageLoader();

Drawable cachedImage = asyncImageLoader.loadDrawable(userIcon,iv, new ImageCallback(){

@Override

public void imageLoaded(Drawable imageDrawable,ImageView imageView, String imageUrl) {

imageView.setImageDrawable(imageDrawable);

}

});

if (cachedImage == null)

{

iv.setImageResource(R.drawable.usericon);

}

else

{

iv.setImageDrawable(cachedImage);

}

if(data.has(“bmiddle_pic”)){

String picurl=data.getString(“bmiddle_pic”);

String picurl2=data.getString(“original_pic”);

ImageView pic=(ImageView)findViewById(R.id.pic);

pic.setTag(picurl2);

pic.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

Object obj=v.getTag();

Intent intent = new Intent(ViewActivity.this,ImageActivity.class);

Bundle b=new Bundle();

b.putString(“url”, obj.toString());

intent.putExtras(b);

[外链图片转存中…(img-RwSas8Wl-1715763900330)]
[外链图片转存中…(img-jycxjz3G-1715763900331)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值