饭否 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>
//推拉和刷新 自定义列表视图 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>
布局都是简单的!只是贴出了它的主要代码!
那它的消息机制是怎样的?它的消息机制都是继承抽象GenericTask完成的!
GenericTask 定义
public abstract class GenericTask extends AsyncTask<TaskParams, Object, TaskResult> implements Observer
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进行数据分析!
该源码易懂,适合学习!
学习的目标是成熟!~~
源码包下载