Sometimes you have to destroy first to create

Re-writing most of the UI for Material compliance. This is going to be a significant effort, but the final product is going to look *much* nicer for it.
This commit is contained in:
Bradlee Speice 2014-12-21 23:23:12 -05:00
parent e1ab61dd5f
commit 51783afc0b
14 changed files with 127 additions and 328 deletions

View File

@ -10,7 +10,7 @@
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme"> android:theme="@style/MinimalBible">
<activity <activity
android:name=".activity.downloader.DownloadActivity" android:name=".activity.downloader.DownloadActivity"
android:label="@string/app_name" /> android:label="@string/app_name" />
@ -21,7 +21,7 @@
android:name=".activity.viewer.BibleViewer" android:name=".activity.viewer.BibleViewer"
android:label="@string/app_name"> android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>

View File

@ -1,8 +1,10 @@
package org.bspeice.minimalbible.activity; package org.bspeice.minimalbible.activity;
import android.app.Activity;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.view.View;
import com.readystatesoftware.systembartint.SystemBarTintManager; import com.readystatesoftware.systembartint.SystemBarTintManager;
@ -14,17 +16,44 @@ import org.bspeice.minimalbible.R;
*/ */
public class BaseActivity extends ActionBarActivity { public class BaseActivity extends ActionBarActivity {
@Override protected static SystemBarTintManager.SystemBarConfig getConfig(Activity context) {
protected void onCreate(Bundle savedInstanceState) { return new SystemBarTintManager(context).getConfig();
super.onCreate(savedInstanceState); }
// Only set the tint if the device is running KitKat or above /**
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { * Calculate the offset we need to display properly if the System bar is translucent
SystemBarTintManager tintManager = new SystemBarTintManager(this); *
tintManager.setStatusBarTintEnabled(true); * @param context The {@link android.app.Activity} we are displaying in
tintManager.setStatusBarTintColor(getResources().getColor( * @param view The {@link android.view.View} we need to calculate the offset for.
R.color.statusbar)); */
} @SuppressWarnings("unused")
} protected static void setInsets(Activity context, View view) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
SystemBarTintManager.SystemBarConfig config = getConfig(context);
view.setPadding(0, config.getPixelInsetTop(true), config.getPixelInsetRight(), config.getPixelInsetBottom());
}
@SuppressWarnings("unused")
protected static void setInsetsSpinner(Activity context, View view) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
SystemBarTintManager.SystemBarConfig config = getConfig(context);
int marginTopBottom = config.getPixelInsetBottom() / 3;
view.setPadding(0, config.getPixelInsetTop(true) + marginTopBottom,
config.getPixelInsetRight(),
marginTopBottom);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Only set the tint if the device is running KitKat or above
// TODO: Can this be set as part of styles.xml?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
SystemBarTintManager tintManager = new SystemBarTintManager(this);
tintManager.setStatusBarTintEnabled(true);
tintManager.setStatusBarTintColor(getResources().getColor(
R.color.colorPrimary));
}
}
} }

View File

@ -89,9 +89,7 @@ public class ListNavAdapter<T> extends BaseAdapter {
public void bind() { public void bind() {
content.setText(object.toString()); content.setText(object.toString());
if (highlighted) { if (highlighted) {
content.setTextColor(v.getResources().getColor(R.color.navbar_highlight)); content.setTextColor(v.getResources().getColor(R.color.colorPrimary));
} else {
content.setTextColor(v.getResources().getColor(R.color.navbar_unhighlighted));
} }
} }
} }

View File

@ -1,49 +1,37 @@
package org.bspeice.minimalbible.activity.viewer; package org.bspeice.minimalbible.activity.viewer;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v7.widget.Toolbar;
import android.support.v4.app.FragmentManager; import android.widget.ArrayAdapter;
import android.support.v4.widget.DrawerLayout; import android.widget.ListView;
import android.support.v7.app.ActionBar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import org.bspeice.minimalbible.Injector; import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MinimalBible; import org.bspeice.minimalbible.MinimalBible;
import org.bspeice.minimalbible.OGHolder; import org.bspeice.minimalbible.OGHolder;
import org.bspeice.minimalbible.R; import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseActivity; import org.bspeice.minimalbible.activity.BaseActivity;
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
import org.bspeice.minimalbible.activity.settings.MinimalBibleSettings;
import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.Book;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import butterknife.ButterKnife;
import butterknife.InjectView;
import dagger.ObjectGraph; import dagger.ObjectGraph;
public class BibleViewer extends BaseActivity implements public class BibleViewer extends BaseActivity implements Injector {
NavDrawerFragment.NavigationDrawerCallbacks,
Injector {
@Inject @Inject
@Named("MainBook") @Named("MainBook")
Book mainBook; Book mainBook;
@InjectView(R.id.navigation_drawer)
ListView drawerContent;
@InjectView(R.id.toolbar)
Toolbar toolbar;
private ObjectGraph bvObjectGraph; private ObjectGraph bvObjectGraph;
/**
* Fragment managing the behaviors, interactions and presentation of the
* navigation drawer.
*/
private BookChapterNavFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in
* {@link #restoreActionBar()}.
*/
private CharSequence mTitle;
/** /**
* Build a scoped object graph for anything used by the BibleViewer * Build a scoped object graph for anything used by the BibleViewer
@ -69,8 +57,6 @@ public class BibleViewer extends BaseActivity implements
/** /**
* Set up the application * Set up the application
* TODO: Get the main book, rather than the first installed book.
*
* @param savedInstanceState Android's savedInstanceState * @param savedInstanceState Android's savedInstanceState
*/ */
@Override @Override
@ -79,75 +65,15 @@ public class BibleViewer extends BaseActivity implements
this.inject(this); this.inject(this);
// If no books are installed, we need to download one first. setContentView(R.layout.activity_bible_viewer);
if (mainBook == null) { ButterKnife.inject(this);
// If there are no books installed...
Log.e(getLocalClassName(), "No books are currently installed, starting DownloadManager");
Intent i = new Intent(BibleViewer.this, DownloadActivity.class);
startActivityForResult(i, 0);
finish();
} else {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment f = BookFragment.newInstance(mainBook.getName());
fragmentManager.beginTransaction()
.replace(R.id.container, f)
.commit();
setContentView(R.layout.activity_bible_viewer);
mNavigationDrawerFragment = (BookChapterNavFragment) getSupportFragmentManager() setSupportActionBar(toolbar);
.findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer. String[] drawerStrings = new String[]{"Content 1", "Content 2"};
mNavigationDrawerFragment.setUp(R.id.navigation_drawer, drawerContent.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
(DrawerLayout) findViewById(R.id.drawer_layout)); drawerStrings));
}
setInsets(this, drawerContent);
} }
@Override
public void onNavigationDrawerItemSelected(int position) {
// Handle a navigation movement
}
public void setActionBarTitle(String title) {
ActionBar actionBar = getSupportActionBar();
mTitle = title;
actionBar.setTitle(title);
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (mNavigationDrawerFragment != null &&
!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
@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 == R.id.action_settings) {
Intent i = new Intent(this, MinimalBibleSettings.class);
startActivityForResult(i, 0);
} else if (id == R.id.action_downloads) {
startActivity(new Intent(this, DownloadActivity.class));
}
return super.onOptionsItemSelected(item);
}
} }

View File

@ -16,7 +16,6 @@ import dagger.Provides;
import de.devland.esperandro.Esperandro; import de.devland.esperandro.Esperandro;
import rx.functions.Action1; import rx.functions.Action1;
import rx.functions.Func1; import rx.functions.Func1;
import rx.subjects.PublishSubject;
/** /**
* Modules used for the BibleViewer activity * Modules used for the BibleViewer activity
@ -24,8 +23,6 @@ import rx.subjects.PublishSubject;
@Module( @Module(
injects = { injects = {
BibleViewer.class, BibleViewer.class,
BookFragment.class,
BookChapterNavFragment.class
} }
) )
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -96,6 +93,8 @@ public class BibleViewerModules {
return new BookManager(); return new BookManager();
} }
/*
Commenting, as I will likely need these in the near future.
@Provides @Provides
@Named("MainAdapter") @Named("MainAdapter")
@Singleton @Singleton
@ -108,4 +107,5 @@ public class BibleViewerModules {
PublishSubject<BookScrollEvent> scrollEventProvider() { PublishSubject<BookScrollEvent> scrollEventProvider() {
return PublishSubject.create(); return PublishSubject.create();
} }
*/
} }

View File

@ -1,52 +0,0 @@
package org.bspeice.minimalbible.activity.viewer;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.navigation.NavDrawerFragment;
import org.crosswire.jsword.book.Book;
import javax.inject.Inject;
import javax.inject.Named;
import rx.subjects.PublishSubject;
/**
* ExpandableListView for managing books of the Bible.
* We extend from @link{BaseNavigationDrawerFragment} so we can inherit some of the lifecycle
* pieces, but the actual view inflation is done by us.
* I tried to refactor this into Kotlin, but I need to inject the vUtil and mainBook,
* and trying to getActivity() as BibleViewer yielded TypeCastException
* TODO: Extend BaseExpNavigationDrawerFragment?
*/
public class BookChapterNavFragment extends NavDrawerFragment {
@Inject @Named("MainBook")
Book mainBook;
@Inject
PublishSubject<BookScrollEvent> scrollListener;
ExpandableListView mActualListView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Injector i = (Injector) getActivity();
i.inject(this);
BibleMenu menu = new BibleMenu(mainBook);
mActualListView = (ExpandableListView) inflater.inflate(
R.layout.fragment_expandable_navigation_drawer, container, false);
mActualListView.setAdapter(menu);
mActualListView.setOnChildClickListener(menu.getMenuClickListener(scrollListener));
mActualListView.setItemChecked(mCurrentSelectedPosition, true);
return mActualListView;
}
}

View File

@ -1,102 +0,0 @@
package org.bspeice.minimalbible.activity.viewer;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.R;
import org.bspeice.minimalbible.activity.BaseFragment;
import org.crosswire.jsword.book.Book;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.ButterKnife;
import butterknife.InjectView;
import rx.subjects.PublishSubject;
/**
* A placeholder fragment containing a simple view.
*/
public class BookFragment extends BaseFragment {
private static final String ARG_BOOK_NAME = "book_name";
Injector i;
@Inject
@Named("MainBook")
Book mBook;
@Inject
PublishSubject<BookScrollEvent> scrollEventProvider;
@Inject
@Named("MainAdapter")
BookAdapter adapter;
@InjectView(R.id.book_content)
RecyclerView bookContent;
/**
* Returns a new instance of this fragment for the given book.
*/
public static BookFragment newInstance(String bookName) {
BookFragment fragment = new BookFragment();
Bundle args = new Bundle();
args.putString(ARG_BOOK_NAME, bookName);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_viewer_main, container,
false);
this.i = (Injector) getActivity();
i.inject(this);
ButterKnife.inject(this, rootView);
// TODO: Load initial text from SharedPreferences, rather than getting the actual book.
displayBook(mBook);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
/*----------------------------------------
Here be all the methods you want to spend time with
----------------------------------------
*/
/**
* Do the initial work of displaying a book. Requires setting up WebView, etc.
* TODO: Get initial content from cache?
*
* @param b The book we want to display
*/
private void displayBook(Book b) {
Log.d("BookFragment", b.getName());
((BibleViewer)getActivity()).setActionBarTitle(b.getInitials());
final RecyclerView.LayoutManager manager = new LinearLayoutManager(getActivity());
bookContent.setLayoutManager(manager);
bookContent.setAdapter(adapter);
adapter.bindScrollHandler(scrollEventProvider, manager);
}
}

View File

@ -92,10 +92,9 @@ class BibleMenu(val b: Book) : BaseExpandableListAdapter() {
val content = bindTo.findViewById(resource) as TextView val content = bindTo.findViewById(resource) as TextView
val resources = bindTo.getResources(): Resources val resources = bindTo.getResources(): Resources
fun getHighlightedColor(highlighted: Boolean) = when(highlighted) { fun getHighlightedColor(highlighted: Boolean) =
true -> resources getColor R.color.navbar_highlight if (highlighted) resources getColor R.color.colorAccent
else -> resources getColor R.color.navbar_unhighlighted // false else resources getColor R.color.textColor
}
fun bind(obj: Any, highlighted: Boolean) { fun bind(obj: Any, highlighted: Boolean) {
content setText obj.toString() content setText obj.toString()

View File

@ -6,37 +6,36 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="org.bspeice.minimalbible.activities.viewer.BibleViewer"> tools:context="org.bspeice.minimalbible.activities.viewer.BibleViewer">
<!-- <!-- Main content -->
As the main content view, the view below consumes the entire <LinearLayout
space available using match_parent in both dimensions.
-->
<FrameLayout
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:fitsSystemWindows="true"
android:fitsSystemWindows="true" /> android:orientation="vertical">
<!-- <android.support.v7.widget.Toolbar
android:layout_gravity="start" tells DrawerLayout to treat android:id="@+id/toolbar"
this as a sliding drawer on the left side for left-to-right android:layout_width="match_parent"
languages and on the right side for right-to-left languages. android:layout_height="wrap_content"
If you're not building against API 17 or higher, use android:background="@color/colorPrimary"
android:layout_gravity="left" instead. android:minHeight="?attr/actionBarSize" />
-->
<!--
The drawer is given a fixed width in dp and extends the full height of
the container.
-->
<fragment <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Main Content" />
</LinearLayout>
<!-- Navigation drawer - layout_gravity:start activates the magic. -->
<ListView
android:id="@+id/navigation_drawer" android:id="@+id/navigation_drawer"
android:name="org.bspeice.minimalbible.activity.viewer.BookChapterNavFragment" style="@style/MinimalBible.NavigationDrawer"
android:layout_width="@dimen/navigation_drawer_width" android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start" android:layout_gravity="start"
android:clipToPadding="false"
android:fitsSystemWindows="true" /> android:fitsSystemWindows="true" />
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View File

@ -7,39 +7,39 @@
android:padding="8dp"> android:padding="8dp">
<TextView <TextView
android:id="@+id/txt_download_item_name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/txt_download_item_name" android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/download_ibtn_download"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium" />
android:layout_alignParentStart="true"
android:layout_toLeftOf="@+id/download_ibtn_download"/>
<TextView <TextView
android:id="@+id/download_txt_item_acronym"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:id="@+id/download_txt_item_acronym"
android:paddingTop="4dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_below="@+id/txt_download_item_name"/> android:layout_below="@+id/txt_download_item_name"
android:paddingTop="4dp"
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageButton <ImageButton
android:id="@+id/download_ibtn_download"
style="@style/MinimalBibleBase.Borderless"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/ic_action_download"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:id="@+id/download_ibtn_download" android:src="@drawable/ic_action_download" />
style="@style/AppBaseTheme.Borderless"/>
<com.todddavies.components.progressbar.ProgressWheel <com.todddavies.components.progressbar.ProgressWheel
android:id="@+id/download_prg_download"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:visibility="gone" android:visibility="gone"
android:id="@+id/download_prg_download" app:barWidth="4dp"
app:rimWidth="0dp" app:rimWidth="0dp" />
app:barWidth="4dp" />
</RelativeLayout> </RelativeLayout>

View File

@ -3,5 +3,4 @@
android:id="@+id/passage" android:id="@+id/passage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical" />
android:textColor="@color/content_text" />

View File

@ -1,12 +1,6 @@
<resources> <resources>
<!-- <style name="MinimalBible" parent="MinimalBibleBase">
Base application theme for API 19+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 19+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<!-- API 19 theme customizations can go here. --> <!-- API 19 theme customizations can go here. -->
<item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item> <item name="android:windowTranslucentNavigation">true</item>
@ -14,7 +8,7 @@
</style> </style>
<style name="ActionBar" parent="@style/Widget.AppCompat.ActionBar"> <style name="ActionBar" parent="@style/Widget.AppCompat.ActionBar">
<item name="android:background">@color/actionbar</item> <item name="android:background">@color/colorPrimary</item>
</style> </style>
</resources> </resources>

View File

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="statusbar">#dddddd</color> <color name="colorPrimary">#f44336</color>
<color name="actionbar">#ffffff</color> <color name="textColorPrimary">#ffffff</color>
<color name="navbar_highlight">#cc0000</color> <color name="colorAccent">#d50000</color>
<color name="navbar_unhighlighted">#000000</color> <color name="textColorAccent">#ffffff</color>
<color name="content_text">#000000</color>
<color name="textColor">#000000</color>
<color name="navigationBackground">#cccccc</color>
<color name="textNavigation">#000</color>
</resources> </resources>

View File

@ -1,16 +1,17 @@
<resources> <resources>
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="AppBaseTheme"> <style name="MinimalBibleBase" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. --> <item name="android:textColorPrimary">@color/textColorPrimary</item>
</style> </style>
<!-- We have a base theme so that KitKat can go translucent here. --> <!-- Actual application style. Allows selective over-riding while inheriting
<style name="AppBaseTheme" parent="Theme.AppCompat.Light" /> from the parent -->
<style name="MinimalBible" parent="MinimalBibleBase" />
<!-- Almost re-use style from Widget.Holo.Button.Borderless --> <!-- Almost re-use style from Widget.Holo.Button.Borderless -->
<style name="AppBaseTheme.Borderless"> <style name="MinimalBibleBase.Borderless">
<item name="android:background">?android:attr/selectableItemBackground</item> <item name="android:background">?android:attr/selectableItemBackground</item>
<item name="android:paddingLeft">4dip</item> <item name="android:paddingLeft">4dip</item>
<item name="android:paddingRight">4dip</item> <item name="android:paddingRight">4dip</item>
<!-- Requires API 17 <!-- Requires API 17
@ -19,4 +20,8 @@
--> -->
</style> </style>
<style name="MinimalBible.NavigationDrawer">
<item name="android:background">@color/navigationBackground</item>
</style>
</resources> </resources>