package com.knight.arch.ui; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.support.design.widget.NavigationView; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.Spinner; import android.widget.TextView; import com.alibaba.fastjson.JSON; import com.knight.arch.R; import com.knight.arch.api.ApiService; import com.knight.arch.api.GitHubApiConstants; import com.knight.arch.api.OAuthGitHubWebFlow; import com.knight.arch.events.LoginUriMsg; import com.knight.arch.model.AccessTokenResponse; import com.knight.arch.model.User; import com.knight.arch.ui.adapter.TrendingReposTimeSpanAdapter; import com.knight.arch.events.TrendingReposTimeSpanTextMsg; import com.knight.arch.module.HomeModule; import com.knight.arch.ui.base.InjectableActivity; import com.knight.arch.ui.fragment.HotReposMainFragment; import com.knight.arch.ui.fragment.HotUsersMainFragment; import com.knight.arch.ui.fragment.LoginDialogFragment; import com.knight.arch.ui.fragment.TrendingReposMainFragment; import com.knight.arch.utils.L; import com.orhanobut.logger.Logger; import com.squareup.picasso.Picasso; import com.umeng.analytics.MobclickAgent; import java.util.Arrays; import java.util.List; import javax.inject.Inject; import de.greenrobot.event.EventBus; import de.hdodenhof.circleimageview.CircleImageView; import rx.Observer; import rx.android.app.AppObservable; import rx.android.schedulers.AndroidSchedulers; import rx.functions.Func1; /** * @author andyiac * @date 15-8-4 * @web http://blog.andyiac.com/ */ public class MainActivity extends InjectableActivity { private HotUsersMainFragment hotUsersFragment; private HotReposMainFragment hotReposFragment; private TrendingReposMainFragment trendingReposMainFragment; private DrawerLayout mDrawerLayout; private ActionBar ab; private Spinner mTrendingSpinner; private CircleImageView imageAvatar; private TextView tvName; private TextView tvHtmlUrl; @Inject OAuthGitHubWebFlow oAuthGitHubWebFlow; @Inject ApiService apiService; @Inject Picasso picasso; private SharedPreferences sharedPreferences; Observer<AccessTokenResponse> tokenObservable = new Observer<AccessTokenResponse>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(AccessTokenResponse accessTokenResponse) { L.json(JSON.toJSONString(accessTokenResponse)); sharedPreferences.edit().putString("token", accessTokenResponse.getAccess_token()).apply(); //拿到token 后就去拿 userInfo getUserInfo(); } }; Observer<Object> userInfoObservable = new Observer<Object>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Object o) { User user = (User) o; L.i("MainActivity after oauth get user info "); L.json(user); sharedPreferences.edit().putString("username", user.getLogin()).apply(); sharedPreferences.edit().putString("avatar_url", user.getAvatar_url()).apply(); sharedPreferences.edit().putString("html_url", user.getHtml_url()).apply(); // 更新DrawerHeader user UI picasso.load(user.getAvatar_url()).into(imageAvatar); tvName.setText(user.getLogin()); tvHtmlUrl.setText(user.getHtml_url()); } }; private void getUserInfo() { String token = sharedPreferences.getString("token", ""); if (!TextUtils.isEmpty(token)) AppObservable.bindActivity(this, apiService.getUserInfoWithToken(token)) .map(new Func1<User, Object>() { @Override public Object call(User user) { return user; } }).observeOn(AndroidSchedulers.mainThread()) .subscribe(userInfoObservable); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); initView(); sharedPreferences = MainActivity.this.getSharedPreferences("githot_sp", MODE_PRIVATE); } public void onResume() { super.onResume(); MobclickAgent.onResume(this); String avatar = sharedPreferences.getString("avatar_url", ""); String uname = sharedPreferences.getString("username", ""); String html_url = sharedPreferences.getString("html_url", ""); if (!TextUtils.isEmpty(avatar) && !TextUtils.isEmpty(uname) && !TextUtils.isEmpty(html_url)) { picasso.load(avatar).into(imageAvatar); tvName.setText(uname); tvHtmlUrl.setText(html_url); } } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } @Override protected int provideContentViewId() { return R.layout.activity_main; } private void initView() { // setStatusColor(android.R.color.transparent); Toolbar toolbar = (Toolbar) findViewById(R.id.id_main_toolbar); setSupportActionBar(toolbar); ab = getSupportActionBar(); if (ab != null) { ab.setHomeAsUpIndicator(R.mipmap.ic_menu); ab.setDisplayHomeAsUpEnabled(true); } View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.trending_repos_time_span, toolbar, false); ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); toolbar.addView(spinnerContainer, lp); //the spinner use below link solution //https://blog.danielbetts.net/2015/01/02/material-design-spinner-toolbar-style-fix/ mTrendingSpinner = (Spinner) spinnerContainer.findViewById(R.id.trending_time_spinner); mTrendingSpinner.setAdapter(new TrendingReposTimeSpanAdapter(this)); mTrendingSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String ts = "daily"; switch (position) { case 0: ts = "daily"; break; case 1: ts = "weekly"; break; case 2: ts = "monthly"; break; } TrendingReposTimeSpanTextMsg msg = new TrendingReposTimeSpanTextMsg(); msg.setTimeSpan(ts); EventBus.getDefault().post(msg); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); if (navigationView != null) { setupDrawerContent(navigationView); navigationView.setCheckedItem(R.id.nav_user_china); initLoginView(navigationView); } selectFragment(R.id.nav_user_china); } private void initLoginView(NavigationView navigationView) { View headerView = navigationView.inflateHeaderView(R.layout.nav_header); imageAvatar = (CircleImageView) headerView.findViewById(R.id.id_nav_header_avatar); tvName = (TextView) headerView.findViewById(R.id.id_nav_header_uname); tvHtmlUrl = (TextView) headerView.findViewById(R.id.id_nav_header_giturl); tvName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openLoginInBrowser(); } }); imageAvatar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openLoginInBrowser(); } }); } private void openLoginInBrowser() { // todo to use HttpUrl.Builder String initialScope = "user,public_repo,repo"; String url = "https://www.github.com/login/oauth/authorize?client_id=" + GitHubApiConstants.GITHUB_APP_CLIENT_ID + "&" + "scope=" + initialScope; LoginDialogFragment loginDialogFragment = new LoginDialogFragment(url); loginDialogFragment.show(getSupportFragmentManager(), "loginDialog"); } //EventBus public void onEvent(LoginUriMsg msg) { // GitHub OAuth // https://developer.github.com/v3/oauth/#web-application-flow Uri uri = msg.getUrl(); if (uri.getQueryParameter("code") != null) { // first step String code = uri.getQueryParameter("code"); // second step getAccessToken(code); } } private void getAccessToken(String code) { String client_id = GitHubApiConstants.GITHUB_APP_CLIENT_ID; String client_secret = GitHubApiConstants.GITHUB_APP_CLIENT_SECRET; AppObservable.bindActivity(this, oAuthGitHubWebFlow.getOAuthToken(client_id, client_secret, code)) .map(new Func1<AccessTokenResponse, AccessTokenResponse>() { @Override public AccessTokenResponse call(AccessTokenResponse accessTokenResponse) { return accessTokenResponse; } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(tokenObservable); } //============================================================================= @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == android.R.id.home) { mDrawerLayout.openDrawer(GravityCompat.START); return true; } //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); return true; } return super.onOptionsItemSelected(item); } @Override public List<Object> getModules() { return Arrays.<Object>asList(new HomeModule(this)); } private void setupDrawerContent(NavigationView navigationView) { navigationView.setNavigationItemSelectedListener( new NavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(MenuItem menuItem) { mDrawerLayout.closeDrawers(); selectFragment(menuItem.getItemId()); return true; } }); } private void selectFragment(int fragmentId) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); hideAllFragment(transaction); switch (fragmentId) { case R.id.nav_user_china: if (hotUsersFragment == null) { hotUsersFragment = new HotUsersMainFragment(); // todo diff with transaction.replace() ? transaction.add(R.id.id_main_frame_container, hotUsersFragment, "hotUser"); } else { transaction.show(hotUsersFragment); } ab.setTitle("Hot users"); break; case R.id.nav_repositories: if (hotReposFragment == null) { hotReposFragment = new HotReposMainFragment(); transaction.add(R.id.id_main_frame_container, hotReposFragment, "hotRepos"); } else { transaction.show(hotReposFragment); } ab.setTitle("Hot repos"); break; case R.id.nav_trending_repos: mTrendingSpinner.setVisibility(View.VISIBLE); if (trendingReposMainFragment == null) { trendingReposMainFragment = new TrendingReposMainFragment(); transaction.add(R.id.id_main_frame_container, trendingReposMainFragment, "TrendingRepos"); } else { transaction.show(trendingReposMainFragment); } ab.setTitle(""); break; } transaction.commit(); } private void hideAllFragment(FragmentTransaction transaction) { if (mTrendingSpinner != null) { mTrendingSpinner.setVisibility(View.GONE); } if (hotUsersFragment != null) { transaction.hide(hotUsersFragment); } if (hotReposFragment != null) { transaction.hide(hotReposFragment); } if (trendingReposMainFragment != null) { transaction.hide(trendingReposMainFragment); } } }