package com.qiwenge.android.act; import android.app.Activity; import android.content.Intent; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.KeyEvent; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; import com.facebook.rebound.SimpleSpringListener; import com.facebook.rebound.Spring; import com.facebook.rebound.SpringSystem; import com.liuguangqiang.framework.utils.DisplayUtils; import com.qiwenge.android.R; import com.qiwenge.android.adapters.ReadMenuAdapter; import com.qiwenge.android.adapters.ReadThemeAdapter; import com.qiwenge.android.async.AsyncUtils; import com.qiwenge.android.base.BaseActivity; import com.qiwenge.android.constant.Constants; import com.qiwenge.android.entity.Book; import com.qiwenge.android.entity.Chapter; import com.qiwenge.android.entity.Mirror; import com.qiwenge.android.entity.Progresses; import com.qiwenge.android.entity.ReadMenu; import com.qiwenge.android.entity.ReadTheme; import com.qiwenge.android.fragments.ReadFragment; import com.qiwenge.android.listeners.ReadPageClickListener; import com.qiwenge.android.ui.OfflineMenu; import com.qiwenge.android.utils.ReaderUtils; import com.qiwenge.android.utils.ScreenBrightnessUtils; import com.qiwenge.android.utils.ThemeUtils; import com.qiwenge.android.utils.book.BookManager; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.OnClick; import de.greenrobot.event.EventBus; import de.greenrobot.event.Subscribe; public class ReadActivity extends BaseActivity { private static final String TAG = "ReadActivity"; /** * 是否初始化完毕。 */ private boolean inited = false; private static final int MESSAGE_SET_BRIGHTNESS = 0x1; /** * 最大屏幕亮度 */ private final static int MAX_BRIGHTNESS = 255; /** * 调节字体大小的SeekBar的最大值 */ private final static int MAX_VALUE_FONTSZIE_SEEKBAR = 100; /** * SeekBar的progrees,缩小5倍为字体偏移量 */ private final static int OFFSET_ZOOM_OUT = 5; /** * 最大字体偏移量 */ private final static int MAX_FONTSIZE_OFFSET = MAX_VALUE_FONTSZIE_SEEKBAR / OFFSET_ZOOM_OUT; /** * 调节屏幕亮度的增量,仅点击亮度按钮时使用 */ private final static int INCREMENT_BRIGHTNESS = 5; /** * 亮度SeekBar的值 */ private int mProgress = 0; /** * 字体大小增量。 */ private int mFontSizeOffest = 0; /** * 原始字体大小。字体大小的调节,在此基础上偏移 */ private int mFontSizeOrigin = Constants.MIN_TEXT_SIZE; /** * 上次修改的字体大小。 */ private int lastTextSize = 0; /** * 章节Id */ public final static String Extra_ChapterId = "chapterId"; public final static String Extra_Book = "book"; private ReadFragment fragment; @InjectView(R.id.layout_read_container) RelativeLayout layoutContainer; @InjectView(R.id.layout_top_menu) RelativeLayout topMenu; @InjectView(R.id.layout_bottom_menu) RelativeLayout layoutBottomMenu; @InjectView(R.id.layout_menu_aa_set) RelativeLayout layoutMenuAaSet; @InjectView(R.id.layout_menu_offline) LinearLayout layoutMenuOffline; @InjectView(R.id.tv_book_title) TextView tvBookTitle; @InjectView(R.id.gv_menu) GridView gvBottomMenu; @InjectView(R.id.offline_menu) OfflineMenu offlineMenu; private GridView gvTheme; private SeekBar seekBarBrightness; private SeekBar seekFontSize; private boolean topIsShow = false; private boolean bottomIsShow = false; private boolean isShowAsSet = false; private boolean isShowOffline = false; private List<ReadMenu> menuData = new ArrayList<>(); private List<ReadTheme> themeData = new ArrayList<>(); private ReadMenuAdapter menuAdapter; private ReadThemeAdapter themeAdapter; /** * 当前选择的主题 */ private int currentTheme = 0; private Handler mHandler = new MyHandler(this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_read); ButterKnife.inject(this); initData(); initViews(); initReadFragment(); getIntentData(); if (!EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().register(this); } } @Override protected void onDestroy() { super.onDestroy(); if (EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().unregister(this); } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent != null && intent.getExtras() != null) { handleExtras(intent.getExtras()); } } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus && !inited) { initListeners(); initTheme(); inited = true; } } @Override protected void onPause() { super.onPause(); ScreenBrightnessUtils.saveScreenBright(getApplicationContext(), mProgress); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_MENU) { showOrHideMenu(); } else if (keyCode == KeyEvent.KEYCODE_BACK) { if (topIsShow) showOrHideMenu(); else finish(); } return true; } private Book book; /** * 获取意图传递的数据,并获取章节详情。 */ private void getIntentData() { Bundle extra = getIntent().getExtras(); handleExtras(extra); } private void handleExtras(Bundle extra) { fragment.clearReader(); if (extra.containsKey(Extra_Book)) { book = extra.getParcelable(Extra_Book); fragment.setBook(book); AsyncUtils.postViewTotal(book.getId()); tvBookTitle.setText(book.title); offlineMenu.setBook(book); } if (extra.containsKey(Extra_ChapterId)) { String chapterId = extra.getString(Extra_ChapterId); getChapter(chapterId); } } @Subscribe public void onEvent(Chapter chapter) { if (offlineMenu != null) { offlineMenu.setChapter(chapter); } } private void getChapter(String chapterId) { if (book != null) { Book record = BookManager.getInstance().getById(book.getId()); if (record != null && record.progresses != null && chapterId.equals(record.progresses.chapter_id)) { int length = record.progresses.chars; fragment.getChapter(chapterId, length); } else { fragment.getChapter(chapterId); } } } /** * 初始化数据,如menu,theme */ private void initData() { String[] titles = getResources().getStringArray(R.array.read_menu_titles); TypedArray icons = getResources().obtainTypedArray(R.array.read_menu_icons); ReadMenu menu; for (int i = 0; i < titles.length; i++) { menu = new ReadMenu(); menu.title = titles[i]; menu.icon = icons.getResourceId(i, R.mipmap.icon_menu_chapters); menuData.add(menu); } int[] themes = {ThemeUtils.NORMAL, ThemeUtils.YELLOW, ThemeUtils.GREEN, ThemeUtils.LEATHER}; ReadTheme theme; for (int i = 0; i < themes.length; i++) { theme = new ReadTheme(); theme.theme = themes[i]; themeData.add(theme); } // 屏幕亮度。 mProgress = ScreenBrightnessUtils.getBrightness(getApplicationContext()); ScreenBrightnessUtils.setBrightness(this, mProgress); } private void initViews() { initBottomMenu(); initBrightnessSeekBar(); initFontSizeSeekBar(); } private void initBottomMenu() { menuAdapter = new ReadMenuAdapter(getApplicationContext(), menuData); gvBottomMenu.setNumColumns(menuData.size()); gvBottomMenu.setAdapter(menuAdapter); themeAdapter = new ReadThemeAdapter(getApplicationContext(), themeData); gvTheme = (GridView) this.findViewById(R.id.gv_theme); gvTheme.setAdapter(themeAdapter); } private void initBrightnessSeekBar() { seekBarBrightness = (SeekBar) this.findViewById(R.id.seekbar_screen_brightness); seekBarBrightness.setMax(MAX_BRIGHTNESS); seekBarBrightness.setProgress(mProgress); seekBarBrightness.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { setBrightness(progress); } } }); } private void initFontSizeSeekBar() { // 字体大小。 seekFontSize = (SeekBar) this.findViewById(R.id.seekBar_font_size); int textSize = ReaderUtils.getTextSize(getApplicationContext()); //字体大小改变的偏移量x5,就是SeekBar的进度 mFontSizeOffest = textSize - mFontSizeOrigin; int progress = mFontSizeOffest * OFFSET_ZOOM_OUT; seekFontSize.setMax(MAX_VALUE_FONTSZIE_SEEKBAR); seekFontSize.setProgress(progress); seekFontSize.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { setReadTextSize(); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { mFontSizeOffest = progress / OFFSET_ZOOM_OUT; } } }); } private void initListeners() { gvBottomMenu.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { switch (arg2) { case 0:// 夜间模式 if (ThemeUtils.isNightModel) { showNighitModel(false); } else { showNighitModel(true); } break; case 1:// Aa if (isShowAsSet) { hideAaSet(); } else { showAaSet(); } break; case 2:// 目录 Bundle extra = new Bundle(); extra.putParcelable(ChapterActivity.EXTRA_BOOK, book); startActivity(ChapterActivity.class, extra); break; case 3: if (isShowOffline) { hideOffline(); } else { showOffline(); } break; default: break; } } }); gvTheme.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectTheme(position, true); } }); } /** * 选择主题。 * * @param i */ private void selectTheme(int i, boolean cacheable) { if (currentTheme >= 0) themeData.get(currentTheme).selected = false; themeData.get(i).selected = true; currentTheme = i; themeAdapter.notifyDataSetChanged(); ThemeUtils.setReaderTheme(themeData.get(i).theme, layoutContainer); ThemeUtils.setNightModle(getApplicationContext(), false); cancelNightModel(); if (cacheable) ThemeUtils.setTheme(getApplicationContext(), themeData.get(i).theme); } private void clearThemeSelected() { themeData.get(currentTheme).selected = false; currentTheme = -1; themeAdapter.notifyDataSetChanged(); } /** * 取消夜间模式 */ private void cancelNightModel() { menuData.get(0).icon = R.mipmap.icon_menu_mode_night; menuData.get(0).title = getString(R.string.reader_night_model); menuAdapter.notifyDataSetChanged(); fragment.refreshTextColor(); } /** * 设置,是否为夜间模式。 * * @param isNight */ private void showNighitModel(boolean isNight) { ThemeUtils.setNightModle(getApplicationContext(), isNight); ThemeUtils.setThemeBg(layoutContainer); if (isNight) { menuData.get(0).icon = R.mipmap.icon_menu_mode_normal; menuData.get(0).title = getString(R.string.reader_normal_model); clearThemeSelected(); } else { selectedLastTheme(); cancelNightModel(); } menuAdapter.notifyDataSetChanged(); fragment.refreshTextColor(); } /** * 初始化主题 */ private void initTheme() { if (ThemeUtils.isNightModel) { showNighitModel(true); } else { selectedLastTheme(); } } /** * 选择原来的主题 */ private void selectedLastTheme() { int theme = ThemeUtils.getCurrentTheme(); for (int i = 0; i < themeData.size(); i++) { if (themeData.get(i).theme == theme) { selectTheme(i, false); break; } } } private SpringSystem springSystem = SpringSystem.create(); private Spring springTopMenu; private Spring springBottomMenu; private Spring springAaSet; private Spring springOffline; private int topMenuTranY; private void animTopMenu(boolean isShow) { if (springTopMenu == null) { springTopMenu = springSystem.createSpring(); springTopMenu.addListener(new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); topMenu.setTranslationY(value); } }); topMenuTranY = topMenu.getHeight() - DisplayUtils.dip2px(this, 20); } springTopMenu.setEndValue(isShow ? topMenuTranY : 0); } private void animBottomMenu(final boolean isShow) { if (springBottomMenu == null) { springBottomMenu = springSystem.createSpring(); springBottomMenu.addListener(new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); layoutBottomMenu.setTranslationY(value); } @Override public void onSpringEndStateChange(Spring spring) { super.onSpringEndStateChange(spring); } }); } springBottomMenu.setEndValue(isShow ? -gvBottomMenu.getHeight() : 0); } private void animAaSet(final boolean isShow) { if (springAaSet == null) { springAaSet = springSystem.createSpring(); springAaSet.addListener(new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); layoutMenuAaSet.setTranslationY(value); } @Override public void onSpringEndStateChange(Spring spring) { super.onSpringEndStateChange(spring); } }); } springAaSet.setEndValue(isShow ? -layoutMenuAaSet.getHeight() : 0); } private void animOffline(final boolean isShow) { if (springOffline == null) { springOffline = springSystem.createSpring(); springOffline.addListener(new SimpleSpringListener() { @Override public void onSpringUpdate(Spring spring) { float value = (float) spring.getCurrentValue(); layoutMenuOffline.setTranslationY(value); } @Override public void onSpringEndStateChange(Spring spring) { super.onSpringEndStateChange(spring); } }); } springOffline.setEndValue(isShow ? -layoutMenuOffline.getHeight() : 0); } private void showTop() { topIsShow = true; animTopMenu(true); } private void hideTop() { topIsShow = false; animTopMenu(false); } private void showBottomMenu() { animBottomMenu(true); bottomIsShow = true; } private void hideBottomMenu() { animBottomMenu(false); hideAaSet(); hideOffline(); bottomIsShow = false; } private void showAaSet() { animAaSet(true); hideOffline(); isShowAsSet = true; } private void hideAaSet() { animAaSet(false); isShowAsSet = false; } private void showOffline() { animOffline(true); hideAaSet(); isShowOffline = true; } private void hideOffline() { animOffline(false); isShowOffline = false; } /** * 显示或者隐藏菜单。 */ private void showOrHideMenu() { handleTop(); handleBottom(); } private void handleTop() { if (topIsShow) hideTop(); else showTop(); } private void handleBottom() { if (bottomIsShow) { hideBottomMenu(); } else { showBottomMenu(); } } /** * 初始化Fragment。 */ private void initReadFragment() { fragment = new ReadFragment(); getSupportFragmentManager().beginTransaction().add(R.id.layout_content, fragment).commit(); fragment.setOnReadPageClickListener(new ReadPageClickListener() { @Override public void onClick() { showOrHideMenu(); } }); } private void setReadTextSize() { int textSize = mFontSizeOrigin + mFontSizeOffest; if (textSize != lastTextSize) { //如果没有修改字体大小,如,来回滑动,不修改阅读器的字体大小 lastTextSize = textSize; fragment.setTextSize(textSize); ReaderUtils.saveTextSize(getApplicationContext(), textSize); } } private void setBrightness(int progress) { mProgress = progress; Message msg = mHandler.obtainMessage(); msg.what = MESSAGE_SET_BRIGHTNESS; msg.arg1 = progress; msg.sendToTarget(); } @OnClick(R.id.layout_top_menu) public void onFinish() { finish(); } @OnClick(R.id.iv_brightness_minus) public void minusBrightness() { mProgress = mProgress - INCREMENT_BRIGHTNESS; if (mProgress < 0) mProgress = 0; seekBarBrightness.setProgress(mProgress); setBrightness(mProgress); } @OnClick(R.id.iv_brightness_plus) public void plusBirghtness() { mProgress = mProgress + INCREMENT_BRIGHTNESS; if (mProgress > MAX_BRIGHTNESS) mProgress = MAX_BRIGHTNESS; seekBarBrightness.setProgress(mProgress); setBrightness(mProgress); } @OnClick(R.id.tv_fontsize_minus) public void minusFontSize() { mFontSizeOffest = mFontSizeOffest - 1; if (mFontSizeOffest < 0) mFontSizeOffest = 0; seekFontSize.setProgress(mFontSizeOffest * OFFSET_ZOOM_OUT); setReadTextSize(); } @OnClick(R.id.tv_fontsize_plus) public void plusFontSize() { mFontSizeOffest = mFontSizeOffest + 1; if (mFontSizeOffest > MAX_FONTSIZE_OFFSET) mFontSizeOffest = MAX_FONTSIZE_OFFSET; seekFontSize.setProgress(mFontSizeOffest * OFFSET_ZOOM_OUT); setReadTextSize(); } /** * 静态的内部类,继承了Handler,防内存泄露 */ private static class MyHandler extends Handler { private WeakReference<Activity> mActivity; public MyHandler(Activity act) { mActivity = new WeakReference<Activity>(act); } @Override public void handleMessage(Message msg) { if (msg.what == MESSAGE_SET_BRIGHTNESS) { ScreenBrightnessUtils.setBrightness(mActivity.get(), msg.arg1); } } } }