实例介绍
【实例简介】
【实例截图】
【核心代码】
/* * The MIT License (MIT) * Copyright (c) 2014 longkai * The software shall be used for good, not evil. */ package org.catnut.ui; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentManager; import android.content.AsyncQueryHandler; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Process; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.text.TextUtils; import android.text.format.DateUtils; import android.view.Gravity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.android.volley.Response; import com.android.volley.VolleyError; import com.google.analytics.tracking.android.EasyTracker; import com.squareup.picasso.Picasso; import org.catnut.R; import org.catnut.api.StuffAPI; import org.catnut.core.CatnutApp; import org.catnut.core.CatnutProvider; import org.catnut.core.CatnutRequest; import org.catnut.fragment.ConversationFragment; import org.catnut.fragment.DraftFragment; import org.catnut.fragment.FavoriteFragment; import org.catnut.fragment.HomeTimelineFragment; import org.catnut.fragment.MentionTimelineFragment; import org.catnut.fragment.MyRelationshipFragment; import org.catnut.fragment.UserTimelineFragment; import org.catnut.metadata.Status; import org.catnut.metadata.User; import org.catnut.metadata.WeiboAPIError; import org.catnut.support.ConfirmBarController; import org.catnut.support.FragmentCallbackFromActivity; import org.catnut.support.QuickReturnScrollView; import org.catnut.util.CatnutUtils; import org.catnut.util.Constants; import org.json.JSONObject; import java.io.File; import java.util.ArrayList; /** * 应用程序主界面。 * * @author longkai */ public class MainActivity extends Activity implements DrawerLayout.DrawerListener, View.OnClickListener, FragmentManager.OnBackStackChangedListener, QuickReturnScrollView.Callbacks { private static final String TAG = "MainActivity"; private ScrollSettleHandler mScrollSettleHandler = new ScrollSettleHandler(); private CatnutApp mApp; private EasyTracker mTracker; private ActionBar mActionBar; private DrawerLayout mDrawerLayout; private View mPlaceholderView; private View mQuickReturnView; private QuickReturnScrollView mQuickReturnDrawer; private ActionBarDrawerToggle mDrawerToggle; private int mMinRawY = 0; private int mState = STATE_ON_SCREEN; private int mQuickReturnHeight; private int mMaxScrollY; private String mNick; private ImageView mProfileCover; private TextView mTextNick; private TextView mDescription; private long mLastFetchMillis; private TextView mFetchNews; private TextView mNewTweet; private TextView mNewMention; private TextView mNewComment; private ConfirmBarController.Callbacks mCallbacks; private FragmentCallbackFromActivity mRefreshCallback; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mApp = CatnutApp.getTingtingApp(); mActionBar = getActionBar(); mActionBar.setIcon(R.drawable.ic_title_home); setContentView(R.layout.main); // drawer specific mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START); mDrawerLayout.setDrawerListener(this); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.open_drawer, R.string.close_drawer); // the whole left drawer mQuickReturnDrawer = (QuickReturnScrollView) findViewById(R.id.drawer); mQuickReturnDrawer.setCallbacks(this); mQuickReturnView = findViewById(R.id.quick_return); mPlaceholderView = findViewById(R.id.place_holder); mQuickReturnDrawer.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { onScrollChanged(mQuickReturnDrawer.getScrollY()); mMaxScrollY = mQuickReturnDrawer.computeVerticalScrollRange() - mQuickReturnDrawer.getHeight(); mQuickReturnHeight = mQuickReturnView.getHeight(); } } ); // drawer customized view mProfileCover = (ImageView) findViewById(R.id.avatar_profile); mTextNick = (TextView) findViewById(R.id.nick); mDescription = (TextView) findViewById(R.id.description); prepareDrawer(); injectListeners(); fetchNews(); if (savedInstanceState == null) { HomeTimelineFragment fragment = HomeTimelineFragment.getFragment(); mCallbacks = fragment; mRefreshCallback = fragment; getFragmentManager() .beginTransaction() .replace(R.id.fragment_container, fragment, HomeTimelineFragment.TAG) .commit(); } getFragmentManager().addOnBackStackChangedListener(this); if (mApp.getPreferences().getBoolean(getString(R.string.pref_enable_analytics), true)) { mTracker = EasyTracker.getInstance(this); } } @Override protected void onStart() { super.onStart(); if (mTracker != null) { mTracker.activityStart(this); } } @Override protected void onStop() { super.onStop(); if (mTracker != null) { mTracker.activityStop(this); } } @Override protected void onSaveInstanceState(Bundle outState) { if (mCallbacks != null) { mCallbacks.onActivitySaveInstanceState(outState); } super.onSaveInstanceState(outState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (mCallbacks != null) { mCallbacks.onActivityRestoreInstanceState(savedInstanceState); } } private void prepareDrawer() { // for drawer mActionBar.setDisplayHomeAsUpEnabled(true); mActionBar.setHomeButtonEnabled(true); // for user' s profile new AsyncQueryHandler(getContentResolver()) { @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { if (cursor.moveToNext()) { mNick = cursor.getString(cursor.getColumnIndex(User.screen_name)); mTextNick.setText(mNick); Picasso.with(MainActivity.this) .load(cursor.getString(cursor.getColumnIndex(User.avatar_large))) .placeholder(R.drawable.error) .error(R.drawable.error) .into(mProfileCover); TextView location = (TextView) findViewById(R.id.location); location.setText(cursor.getString(cursor.getColumnIndex(User.location))); String description = cursor.getString(cursor.getColumnIndex(User.description)); mDescription.setText(TextUtils.isEmpty(description) ? getString(R.string.no_description) : description); View flowingCount = findViewById(R.id.following_count); CatnutUtils.setText(flowingCount, android.R.id.text1, cursor.getString(cursor.getColumnIndex(User.friends_count))); CatnutUtils.setText(flowingCount, android.R.id.text2, getString(R.string.followings)); View flowerCount = findViewById(R.id.followers_count); CatnutUtils.setText(flowerCount, android.R.id.text1, cursor.getString(cursor.getColumnIndex(User.followers_count))); CatnutUtils.setText(flowerCount, android.R.id.text2, getString(R.string.followers)); View tweetsCount = findViewById(R.id.tweets_count); tweetsCount.setOnClickListener(MainActivity.this); flowingCount.setOnClickListener(MainActivity.this); flowerCount.setOnClickListener(MainActivity.this); CatnutUtils.setText(tweetsCount, android.R.id.text1, cursor.getString(cursor.getColumnIndex(User.statuses_count))); CatnutUtils.setText(tweetsCount, android.R.id.text2, getString(R.string.tweets)); } cursor.close(); } }.startQuery( 0, null, CatnutProvider.parse(User.MULTIPLE, mApp.getAccessToken().uid), new String[]{ User.screen_name, User.avatar_large, User.description, User.statuses_count, User.followers_count, User.friends_count, User.verified, User.location }, null, null, null ); } // 更新消息数 private void fetchNews() { if (mFetchNews == null) { mFetchNews = (TextView) findViewById(R.id.fetch_news); mFetchNews.setOnClickListener(this); View newTweet = findViewById(R.id.new_tweet); CatnutUtils.setText(newTweet, android.R.id.text2, getString(R.string.new_tweet_count)); mNewTweet = (TextView) newTweet.findViewById(android.R.id.text1); newTweet.setOnClickListener(this); View newComment = findViewById(R.id.new_comment); mNewComment = (TextView) newComment.findViewById(android.R.id.text1); CatnutUtils.setText(newComment, android.R.id.text2, getString(R.string.new_comment_count)); newComment.setOnClickListener(this); View newMention = findViewById(R.id.new_mention); mNewMention = (TextView) newMention.findViewById(android.R.id.text1); CatnutUtils.setText(newMention, android.R.id.text2, getString(R.string.new_mention_count)); newMention.setOnClickListener(this); } mFetchNews.setText(R.string.loading); mFetchNews.setClickable(false); mApp.getRequestQueue().add(new CatnutRequest( this, StuffAPI.unread_count(mApp.getAccessToken().uid, 0), null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { CatnutUtils.setText(mNewTweet, android.R.id.text1, String.valueOf(response.optInt(Status.SINGLE))); CatnutUtils.setText(mNewComment, android.R.id.text1, String.valueOf(response.optInt("cmt"))); CatnutUtils.setText(mNewMention, android.R.id.text1, String.valueOf(response.optInt("mention_status"))); mLastFetchMillis = System.currentTimeMillis(); mFetchNews.setText(getString(R.string.last_check_time, DateUtils.getRelativeTimeSpanString(mLastFetchMillis))); mFetchNews.setClickable(true); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { WeiboAPIError weiboAPIError = WeiboAPIError.fromVolleyError(error); Toast.makeText(MainActivity.this, weiboAPIError.error, Toast.LENGTH_LONG).show(); mFetchNews.setText(getString(R.string.error_click_try_again)); mFetchNews.setClickable(true); } } )); } private void injectListeners() { findViewById(R.id.action_my_tweets).setOnClickListener(this); findViewById(R.id.action_my_followings).setOnClickListener(this); findViewById(R.id.action_my_followers).setOnClickListener(this); findViewById(R.id.action_my_list).setOnClickListener(this); findViewById(R.id.action_my_favorites).setOnClickListener(this); findViewById(R.id.action_my_drafts).setOnClickListener(this); findViewById(R.id.action_share_app).setOnClickListener(this); findViewById(R.id.action_view_source_code).setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // open or close the drawer if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } switch (item.getItemId()) { // 登出,kill掉本app的进程,不同于按下back按钮,这个不保证回到上一个back stack case R.id.logout: new AlertDialog.Builder(this) .setMessage(getString(R.string.logout_confirm)) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Process.killProcess(Process.myPid()); } }) .setNegativeButton(android.R.string.no, null) .show(); break; // 注销,需要重新授权的 case R.id.cancellation: new AlertDialog.Builder(this) .setMessage(getString(R.string.cancellation_confirm)) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { mApp.invalidateAccessToken(); Intent intent = new Intent(MainActivity.this, HelloActivity.class); // 清除掉之前的back stack哦 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }) .setNegativeButton(android.R.string.no, null) .show(); break; case R.id.pref: startActivity(SingleFragmentActivity.getIntent(this, SingleFragmentActivity.PREF)); break; case R.id.action_compose: startActivity(new Intent(this, ComposeTweetActivity.class)); break; case R.id.fantasy: startActivity(new Intent(this, HelloActivity.class).putExtra(HelloActivity.TAG, HelloActivity.TAG)); break; case R.id.plugins: switch2Plugins(null); break; default: break; } return super.onOptionsItemSelected(item); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onDrawerOpened(View drawerView) { mDrawerToggle.onDrawerOpened(drawerView); mFetchNews.setText(getString(R.string.last_check_time, DateUtils.getRelativeTimeSpanString(mLastFetchMillis))); } @Override public void onDrawerClosed(View drawerView) { mDrawerToggle.onDrawerClosed(drawerView); } @Override public void onDrawerSlide(View drawerView, float slideOffset) { mDrawerToggle.onDrawerSlide(drawerView, slideOffset); } @Override public void onDrawerStateChanged(int newState) { mDrawerToggle.onDrawerStateChanged(newState); } @Override public void onBackStackChanged() { invalidateOptionsMenu(); } @Override public void onClick(View v) { int id = v.getId(); if (id != R.id.fetch_news) { mDrawerLayout.closeDrawer(mQuickReturnDrawer); } Fragment fragment = null; String tag = null; switch (id) { case R.id.tweets_count: case R.id.action_my_tweets: fragment = UserTimelineFragment.getFragment(mApp.getAccessToken().uid, mApp.getPreferences().getString(User.screen_name, null)); tag = UserTimelineFragment.TAG; break; case R.id.following_count: case R.id.action_my_followings: fragment = MyRelationshipFragment.getFragment(true); tag = "true"; break; case R.id.followers_count: case R.id.action_my_followers: fragment = MyRelationshipFragment.getFragment(false); tag = "false"; break; case R.id.action_my_favorites: fragment = FavoriteFragment.getFragment(); tag = FavoriteFragment.TAG; break; case R.id.action_my_drafts: fragment = DraftFragment.getFragment(); tag = DraftFragment.TAG; break; case R.id.action_share_app: Intent intent = new Intent(Intent.ACTION_SEND); intent.setType(getString(R.string.mime_image)); intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_app)); intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_text)); intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(getExternalCacheDir() File.separator Constants.SHARE_IMAGE))); startActivity(intent); return; case R.id.action_view_source_code: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.github_link)))); return; case R.id.fetch_news: fetchNews(); return; case R.id.new_tweet: // 回掉主页时间线 Fragment home = getFragmentManager().findFragmentByTag(HomeTimelineFragment.TAG); // never null, but we still check it. if (home == null || !home.isVisible()) { fragment = HomeTimelineFragment.getFragment(); tag = HomeTimelineFragment.TAG; } else { if (mRefreshCallback != null) { mRefreshCallback.callback(null); } } mNewTweet.setText("0"); break; case R.id.new_mention: fragment = MentionTimelineFragment.getFragment(); tag = MentionTimelineFragment.TAG; mNewMention.setText("0"); break; case R.id.new_comment: fragment = ConversationFragment.getFragment(); tag = ConversationFragment.TAG; break; case R.id.action_my_list: default: Toast.makeText(this, "sorry, not yet implemented =.=", Toast.LENGTH_SHORT).show(); return; } if (fragment != null) { pendingFragment(fragment, tag); } } // 切换到插件,如果没有启用插件则跳转到插件设置界面 public void switch2Plugins(View view) { if (mDrawerLayout.isDrawerOpen(mQuickReturnDrawer)) { mDrawerLayout.closeDrawer(mQuickReturnDrawer); } if (view != null) { // 来自layout xml String key = (String) view.getTag(); SharedPreferences pref = CatnutApp.getTingtingApp().getPreferences(); if (!pref.contains(key)) { // 直接跳到fantasy salutation startActivity(new Intent(this, HelloActivity.class).putExtra(HelloActivity.TAG, HelloActivity.TAG)); return; // stop here } else { boolean enable = pref .getBoolean(key, getResources().getBoolean(R.bool.default_plugin_status)); if (!enable) { startActivity(SingleFragmentActivity.getIntent(this, SingleFragmentActivity.PLUGINS_PREF)); return; // stop here } } } ArrayList<Integer> plugins = CatnutUtils.enabledPlugins(); if (plugins != null) { Intent intent = new Intent(this, PluginsActivity.class); intent.putExtra(PluginsActivity.PLUGINS, plugins); startActivity(intent); } else { startActivity(SingleFragmentActivity.getIntent(this, SingleFragmentActivity.PLUGINS_PREF)); } } /** * 切换fragment,附带一个动画效果 * * @param fragment * @param tag 没有赋null即可 */ private void pendingFragment(Fragment fragment, String tag) { FragmentManager fragmentManager = getFragmentManager(); Fragment tmp = fragmentManager.findFragmentByTag(tag); if (tmp == null || !tmp.isVisible()) { fragmentManager .beginTransaction() .setCustomAnimations( R.animator.fragment_slide_left_enter, R.animator.fragment_slide_left_exit, R.animator.fragment_slide_right_enter, R.animator.fragment_slide_right_exit ) .replace(R.id.fragment_container, fragment, tag) .addToBackStack(null) .commit(); mScrollSettleHandler.post(new Runnable() { @Override public void run() { invalidateOptionsMenu(); } }); } } @Override public void onScrollChanged(int scrollY) { scrollY = Math.min(mMaxScrollY, scrollY); mScrollSettleHandler.onScroll(scrollY); int rawY = mPlaceholderView.getTop() - scrollY; int translationY = 0; switch (mState) { case STATE_OFF_SCREEN: if (rawY <= mMinRawY) { mMinRawY = rawY; } else { mState = STATE_RETURNING; } translationY = rawY; break; case STATE_ON_SCREEN: if (rawY < -mQuickReturnHeight) { mState = STATE_OFF_SCREEN; mMinRawY = rawY; } translationY = rawY; break; case STATE_RETURNING: translationY = (rawY - mMinRawY) - mQuickReturnHeight; if (translationY > 0) { translationY = 0; mMinRawY = rawY - mQuickReturnHeight; } if (rawY > 0) { mState = STATE_ON_SCREEN; translationY = rawY; } if (translationY < -mQuickReturnHeight) { mState = STATE_OFF_SCREEN; mMinRawY = rawY; } break; } mQuickReturnView.animate().cancel(); mQuickReturnView.setTranslationY(translationY scrollY); } @Override public void onDownMotionEvent() { mScrollSettleHandler.setSettleEnabled(false); } @Override public void onUpOrCancelMotionEvent() { mScrollSettleHandler.setSettleEnabled(true); mScrollSettleHandler.onScroll(mQuickReturnDrawer.getScrollY()); } // quick return animation private class ScrollSettleHandler extends Handler { private static final int SETTLE_DELAY_MILLIS = 100; private int mSettledScrollY = Integer.MIN_VALUE; private boolean mSettleEnabled; public void onScroll(int scrollY) { if (mSettledScrollY != scrollY) { // Clear any pending messages and post delayed removeMessages(0); sendEmptyMessageDelayed(0, SETTLE_DELAY_MILLIS); mSettledScrollY = scrollY; } } public void setSettleEnabled(boolean settleEnabled) { mSettleEnabled = settleEnabled; } @Override public void handleMessage(Message msg) { // Handle the scroll settling. if (STATE_RETURNING == mState && mSettleEnabled) { int mDestTranslationY; if (mSettledScrollY - mQuickReturnView.getTranslationY() > mQuickReturnHeight / 2) { mState = STATE_OFF_SCREEN; mDestTranslationY = Math.max( mSettledScrollY - mQuickReturnHeight, mPlaceholderView.getTop()); } else { mDestTranslationY = mSettledScrollY; } mMinRawY = mPlaceholderView.getTop() - mQuickReturnHeight - mDestTranslationY; mQuickReturnView.animate().translationY(mDestTranslationY); } mSettledScrollY = Integer.MIN_VALUE; // reset } } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论