饭否 for Android是一个的迷你博客。在这里你可以告诉大家你在做什么,可以关注一些有趣的人,可以随便看看大家都在做什么。
项目如图:
效果如图:
进入程序,详细看看它是如何实现的!~~~~
它的登陆实现:
//登陆任务类 GenericTask继承Observer(观察者模式)
//观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、
//源-监听器(Source/Listener)模式或从属者(Dependents)模式。
private class LoginTask extends GenericTask
{
private String msg = getString(R.string.login_status_failure);
public String getMsg()
{
return msg;
}
@Override
protected TaskResult _doInBackground(TaskParams... params)
{
//登陆触发
TaskParams param = params[0];
publishProgress(getString(R.string.login_status_logging_in) + "...");
try
{
String username = param.getString("username");
String password = param.getString("password");
//专用函数登陆
user = TwitterApplication.mApi.login(username, password);
TwitterApplication.getMyselfId(true);
TwitterApplication.getMyselfName(true);
} catch (HttpException e)
{
Log.e(TAG, e.getMessage(), e);
// 确切的应该从HttpException中返回的消息中获取错误信息
// Throwable cause = e.getCause(); // Maybe null
// if (cause instanceof HttpAuthException) {
if (e instanceof HttpAuthException)
{
// Invalid userName/password
msg = getString(R.string.login_status_invalid_username_or_password);
} else
{
msg = getString(R.string.login_status_network_or_connection_error);
}
publishProgress(msg);
return TaskResult.FAILED;
}
SharedPreferences.Editor editor = mPreferences.edit();
editor.putString(Preferences.USERNAME_KEY, mUsername);
// add 存储当前用户的id
editor.putString(Preferences.CURRENT_USER_ID, user.getId());
editor.commit();
return TaskResult.OK;
}
}
/**
* 在服务器上验证用户名/密码是否正确,成功则返回该用户信息,失败则抛出异常。
*
* @param username
* @param password
* @return Verified User
* @throws HttpException
* 验证失败及其他非200响应均抛出异常
* @throws OAuthStoreException
*/
public User login(String username, String password) throws HttpException
{
Log.d(TAG, "Login attempt for " + username);
http.setCredentials(username, password);
try
{
// 进行XAuth认证。
((XAuthClient) http.getOAuthClient()).retrieveAccessToken(username,
password);
} catch (Exception e)
{
// TODO: XAuth认证不管是userName/password错,还是appKey错都是返回401 unauthorized
// 但是会返回一个xml格式的error信息,格式如下:
// <hash><request></request><error></error></hash>
throw new HttpAuthException(e.getMessage(), e);
}
// FIXME: 这里重复进行了认证,为历史遗留原因, 留下的唯一原因时该方法需要返回一个User实例
User user = verifyCredentials(); // Verify userName and password
return user;
}
//登陆成功
private void onLoginSuccess()
{
TaskFeedback.getInstance(TaskFeedback.DIALOG_MODE, LoginActivity.this)
.success("");
updateProgress("");
mUsernameEdit.setText("");
mPasswordEdit.setText("");
Log.d(TAG, "Storing credentials.");
TwitterApplication.mApi.setCredentials(mUsername, mPassword);
Intent intent = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
String action = intent.getAction();
if (intent.getAction() == null || !Intent.ACTION_SEND.equals(action))
{
// We only want to reuse the intent if it was photo send.
// Or else default to the main activity.
intent = new Intent(this, TwitterActivity.class);
}
// 发送消息给widget
Intent reflogin = new Intent(this.getBaseContext(), FanfouWidget.class);
reflogin.setAction("android.appwidget.action.APPWIDGET_UPDATE");
PendingIntent l = PendingIntent.getBroadcast(this.getBaseContext(), 0,
reflogin, PendingIntent.FLAG_UPDATE_CURRENT);
try
{
l.send();
} catch (CanceledException e)
{
e.printStackTrace();
}
// 发送消息给widget_small
Intent reflogin2 = new Intent(this.getBaseContext(),
FanfouWidgetSmall.class);
reflogin2.setAction("android.appwidget.action.APPWIDGET_UPDATE");
PendingIntent l2 = PendingIntent.getBroadcast(this.getBaseContext(), 0,
reflogin2, PendingIntent.FLAG_UPDATE_CURRENT);
try
{
l2.send();
} catch (CanceledException e)
{
e.printStackTrace();
}
startActivity(intent);
finish();
}
主界面:
该布局是有一个导航头和一个自定义列表、以及文本视图组成!~
导航头
<include layout="@layout/header" />
<!-- 自定义列表 -->
<com.markupartist.android.widget.PullToRefreshListView
android:id="@+id/tweet_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:divider="@drawable/dashed_line"
android:dividerHeight="1dip"
android:fadeScrollbars="true"
android:fadingEdge="none"
android:fastScrollEnabled="true" />
现在来详细看看导航头以及自定义列表的实现!~
导航头布局:
<?xml version="1.0" encoding="utf-8"?>
<!-- 顶部条 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="47dp"
android:layout_alignParentTop="true"
android:background="@drawable/bg_header"
android:gravity="center_vertical" >
<!-- title -->
<TextView
android:id="@+id/title"
style="@style/logo_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="3dp"
android:layout_marginTop="12dp"
android:background="@null"
android:clickable="true" />
<!-- 搜索按钮 -->
<ImageButton
android:id="@+id/search"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="@null"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:src="@drawable/top_search_selector" />
<!-- 发布消息按钮 -->
<ImageButton
android:id="@+id/writeMessage"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_toLeftOf="@id/search"
android:background="@null"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:src="@drawable/top_msg_selector" />
<!-- 刷新按钮 -->
<ImageButton
android:id="@+id/top_refresh"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_toLeftOf="@id/writeMessage"
android:background="@null"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:src="@drawable/top_refresh_selector" />
<!-- 旋转 -->
<ProgressBar
android:id="@+id/top_refresh_progressBar"
style="?android:progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="@id/top_refresh"
android:visibility="gone" />
<!--
刷新按钮, 旋转效果
<ImageView
android:id="@+id/top_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/writeMessage"
android:layout_centerVertical="true"
android:background="#000"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
/>
-->
<!--
刷新效果测试代码
<ProgressBar
android:id="@+id/temp_id1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/top_refresh"
android:layout_centerVertical="true"
style="?android:progressBarStyleSmall"
/>
<ProgressBar
android:layout_width="32dip"
android:layout_height="32dip"
android:layout_toLeftOf="@id/temp_id1"
android:layout_centerVertical="true"
style="@style/refreshProgressBar"
/>
-->
<!-- Global Progress Bar -->
<ProgressBar
android:id="@+id/progress_bar"
style="@style/gProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_alignParentBottom="true" />
</RelativeLayout>
与导航头布局有一个对应的NavBar类!有个一个超类TwitterListBaseActivity,它有对NavBar的实例化。
//推拉和刷新 自定义列表视图
public class PullToRefreshListView extends ListView implements
OnScrollListener, GestureDetector.OnGestureListener
该类的触发事件如下:
//触碰事件
public boolean onTouchEvent(MotionEvent event)
{
//GestureDetector类定义了许多触摸事件
GestureDetector localGestureDetector = this.mDetector;
localGestureDetector.onTouchEvent(event);
final int y = (int) event.getY();
Log.d(TAG,
String.format(
"[onTouchEvent]event.Action=%d, currState=%d, refreshState=%d,y=%d",
event.getAction(), mCurrentScrollState, mRefreshState,
y));
switch (event.getAction())
{
case MotionEvent.ACTION_UP: //起事件
if (!isVerticalScrollBarEnabled())
{
//是否垂直滚动条
setVerticalScrollBarEnabled(true);
}
if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING)
{
if ((mRefreshView.getBottom() >= mRefreshViewHeight + MAXHEIGHT || mRefreshView
.getTop() >= 0))
{
// Initiate the refresh
mRefreshState = REFRESHING;
//刷新
prepareForRefresh();
onRefresh();
} else if (mRefreshView.getBottom() < mRefreshViewHeight
+ MAXHEIGHT
|| mRefreshView.getTop() <= 0)
{
//中止刷新和落下滚动刷新视图 还原位置
resetHeader();
setSelection(1);
}
}
break;
case MotionEvent.ACTION_DOWN://压事件
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE: //移动事件
//移动事件特效
applyHeaderPadding(event);
break;
}
return super.onTouchEvent(event);
}
//事件特效(padding属性)
private void applyHeaderPadding(MotionEvent ev)
{
final int historySize = ev.getHistorySize();
Log.d(TAG, String.format(
"[applyHeaderPadding]currState=%d, refreshState=%d",
mCurrentScrollState, mRefreshState));
// Workaround for getPointerCount() which is unavailable in 1.5
// (it's always 1 in 1.5)
int pointerCount = 1;
try
{
Method method = MotionEvent.class.getMethod("getPointerCount");
pointerCount = (Integer) method.invoke(ev);
} catch (NoSuchMethodException e)
{
pointerCount = 1;
} catch (IllegalArgumentException e)
{
throw e;
} catch (IllegalAccessException e)
{
System.err.println("unexpected " + e);
} catch (InvocationTargetException e)
{
System.err.println("unexpected " + e);
}
if (mRefreshState == RELEASE_TO_REFRESH)
{
// this.offsetTopAndBottom(-mPadding);
for (int h = 0; h < historySize; h++)
{
for (int p = 0; p < pointerCount; p++)
{
if (isVerticalFadingEdgeEnabled())
{
setVerticalScrollBarEnabled(false);
}
int historicalY = 0;
try
{
// For Android > 2.0
Method method = MotionEvent.class.getMethod(
"getHistoricalY", Integer.TYPE, Integer.TYPE);
historicalY = ((Float) method.invoke(ev, p, h))
.intValue();
} catch (NoSuchMethodException e)
{
// For Android < 2.0
historicalY = (int) (ev.getHistoricalY(h));
} catch (IllegalArgumentException e)
{
throw e;
} catch (IllegalAccessException e)
{
System.err.println("unexpected " + e);
} catch (InvocationTargetException e)
{
System.err.println("unexpected " + e);
}
// Calculate the padding to apply, we divide by 1.7 to
// simulate a more resistant effect during pull.
int topPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7);
// Log.d(TAG,
// String.format(
// "[applyHeaderPadding]historicalY=%d,topPadding=%d,mRefreshViewHeight=%d,mLastMotionY=%d",
// historicalY, topPadding,
// mRefreshViewHeight, mLastMotionY));
mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
topPadding, mRefreshView.getPaddingRight(),
mRefreshView.getPaddingBottom());
}
}
}
}
这样就可以达到拖动效果了!~
那如何实现自定义对话框?如下效果:
饭否重写了Dialog类!
public class MenuDialog extends Dialog
布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<GridView
android:id="@+id/mygridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:horizontalSpacing="10dp"
android:numColumns="3"
android:padding="10dp"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp" >
</GridView>
<Button
android:id="@+id/close_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="close"
android:visibility="gone" />
</RelativeLayout>
原来是网格布局!~~~
// 网格事件 绑定监听器
gridview.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v,
int position, long id)
{
switch (position)
{
case PAGE_MINE:
String user = TwitterApplication.getMyselfId(false);
String name = TwitterApplication.getMyselfName(false);
Intent intent = UserTimelineActivity.createIntent(user,
name);
goTo(UserTimelineActivity.class, intent);
break;
case PAGE_PROFILE:
goTo(ProfileActivity.class);
break;
case PAGE_FOLLOWERS:
goTo(FollowersActivity.class);
break;
case PAGE_FOLLOWING:
goTo(FollowingActivity.class);
break;
case PAGE_HOME:
goTo(TwitterActivity.class);
break;
case PAGE_MENTIONS:
goTo(MentionActivity.class);
break;
case PAGE_BROWSE:
goTo(BrowseActivity.class);
break;
case PAGE_FAVORITES:
goTo(FavoritesActivity.class);
break;
case PAGE_MESSAGE:
goTo(DmActivity.class);
break;
}
}
});
我的空间界面是如何实现的?效果如下:
这主要是取决于它的布局!布局如下:
<?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="@color/body_background"
android:orientation="vertical" >
<!-- Header -->
<include layout="@layout/header" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFEFF0F4"
android:scrollbars="horizontal" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFEFF0F4"
android:orientation="vertical" >
<!-- 头像部分 -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10.0dip"
android:background="#FFEFF0F4"
android:orientation="vertical" >
<!-- 头像图片 -->
<ImageView
android:id="@+id/profileimage"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginRight="5.0dip" >
</ImageView>
<!-- 用户昵称 -->
<TextView
android:id="@+id/profilescreenname"
style="@style/LinkText.Bold.Huge"
android:layout_width="fill_parent"
android:layout_height="24.0dip"
android:layout_toRightOf="@id/profileimage" >
</TextView>
<!-- 用户名。。Email? -->
<TextView
android:id="@+id/profilename"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/profilescreenname"
android:layout_toRightOf="@id/profileimage" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="vertical" >
<!-- 发送回复 -->
<Button
android:id="@+id/sendmetion_btn"
style="@style/Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_marginRight="10.0dip"
android:text="@string/profile_send_mention"
android:visibility="gone" />
<!-- 发送私信 -->
<Button
android:id="@+id/senddm_btn"
style="@style/Button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10.0dip"
android:text="@string/profile_send_dm"
android:visibility="gone" />
</LinearLayout>
</RelativeLayout>
<!-- 操作按钮部分 -->
<RelativeLayout
android:id="@+id/relative_following"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10.0dip"
android:background="@drawable/panel_bg" >
<TextView
android:id="@+id/isfollowing_text"
style="@style/normalText.span"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="10.0dip"
android:textSize="16.0sp" >
</TextView>
<!-- 关注/取消关注 按钮 -->
<Button
android:id="@+id/following_btn"
style="@style/Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerInParent="true"
android:layout_marginRight="10.0dip"
android:drawablePadding="5dip"
android:visibility="gone" />
</RelativeLayout>
<!-- 基本信息部分 -->
<RelativeLayout
android:id="@+id/relative_3"
android:layout_width="fill_parent"
android:layout_height="100.0dip"
android:layout_margin="10.0dip"
android:background="@drawable/panel_bg" >
<TextView
android:id="@+id/user_location_title"
style="@style/normalText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dip"
android:layout_marginTop="10.0dip"
android:gravity="center_vertical"
android:text="@string/profile_user_location_title"
android:textColor="#FF7D899D"
android:textSize="16.0sp" >
</TextView>
<!-- 所在地 -->
<TextView
android:id="@+id/user_location"
style="@style/normalText.span"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/user_location_title"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/user_location_title"
android:textSize="16.0sp" >
</TextView>
<!-- 分隔条 -->
<View
android:id="@+id/view_3"
android:layout_width="fill_parent"
android:layout_height="1.0dip"
android:layout_centerVertical="true"
android:background="@drawable/horizontal_separation_line" >
</View>
<!-- 网站 -->
<TextView
android:id="@+id/user_url_title"
style="@style/normalText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/user_location_title"
android:layout_alignParentBottom="true"
android:layout_below="@id/view_3"
android:gravity="center_vertical"
android:text="@string/profile_user_url_title"
android:textColor="#FF7D899D"
android:textSize="16.0sp" >
</TextView>
<TextView
android:id="@+id/user_url"
style="@style/normalText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@id/view_3"
android:layout_marginLeft="10.0dip"
android:layout_toRightOf="@id/user_url_title"
android:autoLink="web"
android:gravity="center_vertical"
android:singleLine="true"
android:textSize="16.0sp" >
</TextView>
</RelativeLayout>
<!-- 自我描述部分 -->
<RelativeLayout
android:id="@+id/relative_user_info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10.0dip"
android:background="@drawable/panel_bg"
android:padding="20.0dip" >
<TextView
android:id="@+id/tweet_user_info"
style="@style/normalText"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</TextView>
</RelativeLayout>
<!-- 按钮面板部分 -->
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="130.0dip"
android:layout_margin="10.0dip"
android:background="@drawable/panel_bg" >
<!-- 垂直分隔条 -->
<View
android:id="@+id/view_one"
android:layout_width="1.0dip"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:background="@drawable/vertical_separation_line_repeat" >
</View>
<!-- 水平分隔条 -->
<View
android:id="@+id/view_two"
android:layout_width="fill_parent"
android:layout_height="1.0dip"
android:layout_centerVertical="true"
android:background="@drawable/horizontal_separation_line_repeat" >
</View>
<!-- ta跟随的人 按钮 -->
<RelativeLayout
android:id="@+id/friendsLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/view_two"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/view_one"
android:background="@drawable/bg_panel_above_left"
android:clickable="true" >
<!-- ta跟随的人数 -->
<TextView
android:id="@+id/friends_count"
style="@style/normalText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="10.0dip"
android:gravity="center"
android:text="0" >
</TextView>
<!-- ta跟随的人 -->
<TextView
android:id="@+id/friends_count_title"
style="@style/normalText.span"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/friends_count"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/profile_friends_count_title" >
</TextView>
</RelativeLayout>
<!-- 跟随ta的人 按钮 -->
<LinearLayout
android:id="@+id/followersLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/view_two"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/view_one"
android:background="@drawable/bg_panel_above_right"
android:clickable="true"
android:orientation="vertical" >
<!-- 跟随ta的人数 -->
<TextView
android:id="@+id/followers_count"
style="@style/normalText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10.0dip"
android:gravity="center"
android:text="0" >
</TextView>
<TextView
android:id="@+id/followers_count_title"
style="@style/normalText.span"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="@string/profile_followers_count_title" >
</TextView>
</LinearLayout>
<!--
消息TODO:有bug 同样的布局,却不居中,
需要加padding-right,
怀疑资源图片中patches有问题
还好横屏竖屏都没问题
-->
<LinearLayout
android:id="@+id/statusesLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@id/view_two"
android:layout_toLeftOf="@id/view_one"
android:background="@drawable/bg_panel_below_left"
android:clickable="true"
android:orientation="vertical"
android:paddingRight="10dp" >
<!-- 消息数 -->
<TextView
android:id="@+id/statuses_count"
style="@style/normalText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10.0dip"
android:gravity="center"
android:text="0" >
</TextView>
<TextView
android:id="@+id/statuses_count_title"
style="@style/normalText.span"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="@string/profile_statuses_count_title" >
</TextView>
</LinearLayout>
<!-- 收藏按钮 -->
<LinearLayout
android:id="@+id/favouritesLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/view_two"
android:layout_toRightOf="@+id/view_one"
android:background="@drawable/bg_panel_below_right"
android:clickable="true"
android:orientation="vertical" >
<!-- 收藏数 -->
<TextView
android:id="@+id/favourites_count"
style="@style/normalText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10.0dip"
android:gravity="center"
android:text="0" >
</TextView>
<TextView
android:id="@+id/favourites_count_title"
style="@style/normalText.span"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="@string/profile_favourites_count_title" >
</TextView>
</LinearLayout>
</RelativeLayout>
<!--
扩展用
<LinearLayout
android:orientation="vertical"
android:background="@drawable/panel_bg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10.0dip"
>
<RelativeLayout
android:id="@+id/relativelayout_7"
android:focusable="true"
android:clickable="true"
android:layout_width="fill_parent"
android:layout_height="43.0dip"
>
<TextView
android:id="@+id/textview_15"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:text="test"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
</TextView>
<TextView
android:id="@+id/textview_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:text="0"
android:layout_toRightOf="@+id/textview_15"
android:layout_centerVertical="true"
>
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20.0dip"
android:src="@drawable/icon"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
>
</ImageView>
</RelativeLayout>
<View
android:id="@+id/view_4"
android:background="@drawable/horizontal_separation_line_repeat"
android:layout_width="fill_parent"
android:layout_height="1.0dip"
android:layout_centerVertical="true"
>
</View>
<RelativeLayout
android:id="@+id/relativelayout_7"
android:focusable="true"
android:clickable="true"
android:layout_width="fill_parent"
android:layout_height="43.0dip"
>
<TextView
android:id="@+id/textview_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:text="tsss"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20.0dip"
android:src="@drawable/icon"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
>
</ImageView>
</RelativeLayout>
</LinearLayout>
-->
<!--
TODO 工具栏
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10.0dip"
>
<RelativeLayout
android:id="@+id/relativelayout_7"
android:focusable="true"
android:clickable="true"
android:layout_width="fill_parent"
android:layout_height="43.0dip"
>
<TextView
android:id="@+id/textview_16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10.0dip"
android:text="tsss"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
>
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="20.0dip"
android:src="@drawable/icon"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
>
</ImageView>
</RelativeLayout>
</LinearLayout>
-->
</LinearLayout>
</ScrollView>
</LinearLayout>
实现就是这么简单!~
看看它的搜索效果如图:
布局如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/body_background"
android:orientation="vertical" >
<!-- Header -->
<include layout="@layout/header_search" />
<!-- 复合列表,包含保存的搜索和热门搜索 -->
<ListView
android:id="@+id/search_section_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:divider="@drawable/dashed_line"
android:dividerHeight="1dip"
android:fadeScrollbars="true"
android:fastScrollEnabled="true" />
</LinearLayout>
对应的类SearchActivity,而搜索是在SearchResultActivity中由SearchTask完成的!
布局都是简单的!只是贴出了它的主要代码!
那它的消息机制是怎样的?它的消息机制都是继承抽象GenericTask完成的!
GenericTask 定义
public abstract class GenericTask extends
AsyncTask<TaskParams, Object, TaskResult> implements Observer
AsyncTask是抽象类,子类必须实现抽象方法doInBackground(Params... p) ,在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Result r)方法,因为应用程序关心的结果在此方法中返回。
AsyncTask 的执行分为四个步骤,与前面定义的TaskListener类似。每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用。
* onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。
* doInBackground(Params...) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress...)来更新任务的进度。
* onProgressUpdate(Progress...) 此方法在主线程执行,用于显示任务执行的进度。
* onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回。
原来它的消息是这样的呀!~~~~
它的图片操作又是怎样的?
它操作图片的类有
ImageManager:管理图标图像的检索和存储、 使用put方法来下载和存储图像、使用get方法来检索图像的经理。
LazyImageLoader:异步图片加载。
MemoryImageCache:管理内存图片缓冲。
SimpleImageLoader:使用了LazyImageLoader加载图片。
CallbackManager: 当图片加载完成后就会触发完成回调函数!~
如此简单!~~~
它使用Auth认证与服务器进行了交流!~分析如下:
XAuthClient类继承OAuthClient类,实现了Auth自定义信息操作的类,与服务器交流如下:
public void retrieveAccessToken(String username, String password)
throws OAuthStoreException, ClientProtocolException, IOException,
ResponseException
{
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(BASE_URL + "/access_token");
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(
CONSUMER_KEY, CONSUMER_SECRET);
List<BasicNameValuePair> params = Arrays.asList(new BasicNameValuePair(
"x_auth_username", username), new BasicNameValuePair(
"x_auth_password", password), new BasicNameValuePair(
"x_auth_mode", "client_auth"));
UrlEncodedFormEntity entity = null;
try
{
entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
} catch (UnsupportedEncodingException e)
{
throw new RuntimeException("wtf");
}
request.setEntity(entity);
try
{
consumer.sign(request);
} catch (OAuthMessageSignerException e)
{
e.printStackTrace();
} catch (OAuthExpectationFailedException e)
{
e.printStackTrace();
} catch (OAuthCommunicationException e)
{
e.printStackTrace();
}
HttpResponse response = client.execute(request);
String responseString = Response.entityToString(response.getEntity());
String[] tmp = TextUtils.split(responseString, "&");
if (tmp.length < 2)
{
Log.e(TAG, "something wrong with access token response: "
+ responseString);
return;
}
String token = tmp[0].replace("oauth_token=", "");
String tokenSerect = tmp[1].replace("oauth_token_secret=", "");
mAccessToken = new OAuthAccessToken(token, tokenSerect);
storeAccessToken();
logger.info("retrieve access token with request token "
+ mConsumer.getToken() + " " + mAccessToken + " "
+ mProvider.getAccessTokenEndpointUrl());
}
其实关键与服务器交流的获取用户信息等操作都在Weibo类中,Weibo类通过HttpClient向服务器发送请求参数,服务器接收到参数后信息给weibo,weibo进行数据分析!
该源码易懂,适合学习!
学习的目标是成熟!~~