diff options
author | Allan Wang <me@allanwang.ca> | 2017-07-08 20:25:23 -0700 |
---|---|---|
committer | Allan Wang <me@allanwang.ca> | 2017-07-08 20:25:23 -0700 |
commit | 81996038462de1be86643e95d262933c4b96c551 (patch) | |
tree | 39423b28217251e7051f86e9e4f80c47bcba20b2 /about/src | |
parent | 880d433e475e5be4e5d91afac145b490f9a959b7 (diff) | |
download | kau-81996038462de1be86643e95d262933c4b96c551.tar.gz kau-81996038462de1be86643e95d262933c4b96c551.tar.bz2 kau-81996038462de1be86643e95d262933c4b96c551.zip |
Move components to separate modules
Diffstat (limited to 'about/src')
14 files changed, 779 insertions, 0 deletions
diff --git a/about/src/androidTest/java/ca/allanwang/kau/ExampleInstrumentedTest.java b/about/src/androidTest/java/ca/allanwang/kau/ExampleInstrumentedTest.java new file mode 100644 index 0000000..7b079b2 --- /dev/null +++ b/about/src/androidTest/java/ca/allanwang/kau/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package ca.allanwang.kau; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumentation test, which will execute on an Android device. + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("ca.allanwang.kau.test", appContext.getPackageName()); + } +} diff --git a/about/src/main/AndroidManifest.xml b/about/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9c9b9e6 --- /dev/null +++ b/about/src/main/AndroidManifest.xml @@ -0,0 +1 @@ +<manifest package="ca.allanwang.kau.about" /> diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt new file mode 100644 index 0000000..4751a09 --- /dev/null +++ b/about/src/main/kotlin/ca/allanwang/kau/about/AboutActivityBase.kt @@ -0,0 +1,248 @@ +package ca.allanwang.kau.about + +import android.graphics.drawable.Drawable +import android.os.Bundle +import android.support.v4.view.PagerAdapter +import android.support.v4.view.ViewPager +import android.support.v7.app.AppCompatActivity +import android.support.v7.widget.RecyclerView +import android.transition.TransitionInflater +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import ca.allanwang.kau.R +import ca.allanwang.kau.adapters.FastItemThemedAdapter +import ca.allanwang.kau.adapters.ThemableIItemColors +import ca.allanwang.kau.adapters.ThemableIItemColorsDelegate +import ca.allanwang.kau.animators.FadeScaleAnimator +import ca.allanwang.kau.iitems.CutoutIItem +import ca.allanwang.kau.iitems.HeaderIItem +import ca.allanwang.kau.iitems.LibraryIItem +import ca.allanwang.kau.utils.* +import ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout +import ca.allanwang.kau.ui.widgets.InkPageIndicator +import com.mikepenz.aboutlibraries.Libs +import com.mikepenz.aboutlibraries.entity.Library +import com.mikepenz.fastadapter.IItem +import org.jetbrains.anko.doAsync +import org.jetbrains.anko.uiThread +import java.security.InvalidParameterException + +/** + * Created by Allan Wang on 2017-06-28. + * + * Floating About Activity Panel for your app + * This contains all the necessary layouts, and can be extended and configured using the [configBuilder] + * The [rClass] is necessary to generate the list of libraries used in your app, and should point to your app's + * R.string::class.java + * If you don't need auto detect, you can pass null instead + * Note that for the auto detection to work, the R fields must be excluded from Proguard + * Manual lib listings and other extra modifications can be done so by overriding the open functions + */ +abstract class AboutActivityBase(val rClass: Class<*>?, val configBuilder: Configs.() -> Unit = {}) : AppCompatActivity(), ViewPager.OnPageChangeListener { + + val draggableFrame: ElasticDragDismissFrameLayout by bindView(R.id.about_draggable_frame) + val pager: ViewPager by bindView(R.id.about_pager) + val indicator: InkPageIndicator by bindView(R.id.about_indicator) + /** + * Holds some common configurations that may be added directly from the constructor + * Applied lazily since it needs the context to fetch resources + */ + val configs: Configs by lazy { Configs().apply { configBuilder() } } + /** + * Number of pages in the adapter + * Defaults to just the main view and lib view + */ + open val pageCount: Int = 2 + /** + * Page position for the libs + * This is generated automatically if [inflateLibPage] is called + */ + private var libPage: Int = -2 + /** + * Holds that status of each page + * 0 means nothing has happened + * 1 means this page has been in view at least once + * The rest is up to you + */ + lateinit var pageStatus: IntArray + /** + * Holds the lib items once they are fetched asynchronously + */ + var libItems: List<LibraryIItem>? = null + /** + * Holds the adapter for the library page; this is generated later because it uses the config colors + */ + lateinit var libAdapter: FastItemThemedAdapter<IItem<*, *>> + /** + * Global reference of the library recycler + * This is set by default through [inflateLibPage] and is used to stop scrolling + * When the draggable frame exits + * It is not required, hence its nullability + */ + private var libRecycler: RecyclerView? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.kau_activity_about) + pageStatus = IntArray(pageCount) + libAdapter = FastItemThemedAdapter(configs) + LibraryIItem.bindClickEvents(libAdapter) + if (configs.textColor != null) indicator.setColour(configs.textColor!!) + with(pager) { + adapter = AboutPagerAdapter() + pageMargin = dimenPixelSize(R.dimen.kau_spacing_normal) + addOnPageChangeListener(this@AboutActivityBase) + } + indicator.setViewPager(pager) + draggableFrame.addListener(object : ElasticDragDismissFrameLayout.SystemChromeFader(this) { + override fun onDragDismissed() { + // if we drag dismiss downward then the default reversal of the enter + // transition would slide content upward which looks weird. So reverse it. + if (draggableFrame.translationY > 0) { + window.returnTransition = TransitionInflater.from(this@AboutActivityBase) + .inflateTransition(configs.transitionExitReversed) + } + libRecycler?.stopScroll() + finishAfterTransition() + } + }) + } + + inner class Configs : ThemableIItemColors by ThemableIItemColorsDelegate() { + var cutoutTextRes: Int = -1 + var cutoutText: String? = null + var cutoutDrawableRes: Int = -1 + var cutoutDrawable: Drawable? = null + var cutoutForeground: Int? = null + var libPageTitleRes: Int = -1 + var libPageTitle: String? = string(R.string.kau_about_libraries_intro) //This is in the string by default since it's lower priority + /** + * Transition to be called if the view is dragged down + */ + var transitionExitReversed: Int = R.transition.kau_about_return_downward + } + + /** + * Method to fetch the library list + * This is fetched asynchronously and you may override it to customize the list + */ + open fun getLibraries(libs: Libs): List<Library> = libs.prepareLibraries(this, null, null, true, true) + + /** + * Gets the view associated with the given page position + * Keep in mind that when inflating, do NOT add the view to the viewgroup + * Use layoutInflater.inflate(id, parent, false) + */ + open fun getPage(position: Int, layoutInflater: LayoutInflater, parent: ViewGroup): View { + return when (position) { + 0 -> inflateMainPage(layoutInflater, parent, position) + pageCount - 1 -> inflateLibPage(layoutInflater, parent, position) + else -> throw InvalidParameterException() + } + } + + /** + * Create the main view with the cutout + */ + open fun inflateMainPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View { + val fastAdapter = FastItemThemedAdapter<IItem<*, *>>(configs) + val recycler = fullLinearRecycler(fastAdapter) + fastAdapter.add(CutoutIItem { + with(configs) { + text = string(cutoutTextRes, cutoutText) + drawable = drawable(cutoutDrawableRes, cutoutDrawable) + if (configs.cutoutForeground != null) foregroundColor = configs.cutoutForeground!! + } + }.apply { + themeEnabled = configs.cutoutForeground == null + }) + postInflateMainPage(fastAdapter) + return recycler + } + + /** + * Open hook called just before the main page view is returned + * Feel free to add your own items to the adapter in here + */ + open fun postInflateMainPage(adapter: FastItemThemedAdapter<IItem<*, *>>) { + + } + + /** + * Create the lib view with the list of libraries + */ + open fun inflateLibPage(layoutInflater: LayoutInflater, parent: ViewGroup, position: Int): View { + libPage = position + val v = layoutInflater.inflate(R.layout.kau_recycler_detached_background, parent, false) + val recycler = v.findViewById<RecyclerView>(R.id.kau_recycler_detached) + libRecycler = recycler + recycler.adapter = libAdapter + recycler.itemAnimator = FadeScaleAnimator(itemDelayFactor = 0.2f).apply { addDuration = 300; interpolator = AnimHolder.decelerateInterpolator(this@AboutActivityBase) } + val background = v.findViewById<View>(R.id.kau_recycler_detached_background) + if (configs.backgroundColor != null) background.setBackgroundColor(configs.backgroundColor!!.colorToForeground()) + doAsync { + libItems = getLibraries( + if (rClass == null) Libs(this@AboutActivityBase) else Libs(this@AboutActivityBase, Libs.toStringArray(rClass.fields)) + ).map { LibraryIItem(it) } + if (libPage >= 0 && pageStatus[libPage] == 1) + uiThread { addLibItems() } + } + return v + } + + inner class AboutPagerAdapter : PagerAdapter() { + + private val layoutInflater: LayoutInflater = LayoutInflater.from(this@AboutActivityBase) + private val views = Array<View?>(pageCount) { null } + + override fun instantiateItem(collection: ViewGroup, position: Int): Any { + val layout = getPage(position, collection) + collection.addView(layout) + return layout + } + + override fun destroyItem(collection: ViewGroup, position: Int, view: Any) { + collection.removeView(view as View) + views[position] = null + } + + override fun getCount(): Int = pageCount + + override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` + + /** + * Only get page if view does not exist + */ + private fun getPage(position: Int, parent: ViewGroup): View { + if (views[position] == null) views[position] = getPage(position, layoutInflater, parent) + return views[position]!! + } + } + + override fun onPageScrollStateChanged(state: Int) {} + + override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} + + override fun onPageSelected(position: Int) { + if (pageStatus[position] == 0) pageStatus[position] = 1 // mark as seen if previously null + if (position == libPage && libItems != null && pageStatus[position] == 1) { + pageStatus[position] = 2 //add libs and mark as such + postDelayed(300) { addLibItems() } //delay so that the animations occur once the page is fully switched + } + } + + /** + * Function that is called when the view is ready to add the lib items + * Feel free to add your own items here + */ + open fun addLibItems() { + libAdapter.add(HeaderIItem(text = configs.libPageTitle, textRes = configs.libPageTitleRes)) + .add(libItems) + } + + override fun onDestroy() { + AnimHolder.decelerateInterpolator.invalidate() //clear the reference to the interpolators we've used + super.onDestroy() + } +}
\ No newline at end of file diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt new file mode 100644 index 0000000..34e8641 --- /dev/null +++ b/about/src/main/kotlin/ca/allanwang/kau/about/CutoutIItem.kt @@ -0,0 +1,48 @@ +package ca.allanwang.kau.about + +import android.support.v7.widget.RecyclerView +import android.view.View +import ca.allanwang.kau.R +import ca.allanwang.kau.adapters.ThemableIItem +import ca.allanwang.kau.adapters.ThemableIItemDelegate +import ca.allanwang.kau.ui.views.CutoutView +import ca.allanwang.kau.utils.bindView +import com.mikepenz.fastadapter.items.AbstractItem + +/** + * Created by Allan Wang on 2017-06-28. + * + * Just a cutout item with some defaults in [R.layout.kau_iitem_cutout] + */ +class CutoutIItem(val config: CutoutView.() -> Unit = {} +) : AbstractItem<CutoutIItem, CutoutIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() { + + override fun getType(): Int = R.id.kau_item_cutout + + override fun getLayoutRes(): Int = R.layout.kau_iitem_cutout + + override fun isSelectable(): Boolean = false + + override fun bindView(holder: ViewHolder, payloads: MutableList<Any>?) { + super.bindView(holder, payloads) + with(holder) { + if (accentColor != null && themeEnabled) cutout.foregroundColor = accentColor!! + cutout.config() + } + } + + override fun unbindView(holder: ViewHolder) { + super.unbindView(holder) + with(holder) { + cutout.drawable = null + cutout.text = "Text" //back to default + } + } + + override fun getViewHolder(v: View): ViewHolder = ViewHolder(v) + + class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { + val cutout: CutoutView by bindView(R.id.kau_cutout) + } + +}
\ No newline at end of file diff --git a/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt new file mode 100644 index 0000000..1b832a2 --- /dev/null +++ b/about/src/main/kotlin/ca/allanwang/kau/about/LibraryIItem.kt @@ -0,0 +1,99 @@ +package ca.allanwang.kau.about + +import android.os.Build +import android.support.v7.widget.CardView +import android.support.v7.widget.RecyclerView +import android.text.Html +import android.view.View +import android.widget.TextView +import ca.allanwang.kau.R +import ca.allanwang.kau.adapters.ThemableIItem +import ca.allanwang.kau.adapters.ThemableIItemDelegate +import ca.allanwang.kau.utils.bindView +import ca.allanwang.kau.utils.gone +import ca.allanwang.kau.utils.startLink +import ca.allanwang.kau.utils.visible +import com.mikepenz.aboutlibraries.entity.Library +import com.mikepenz.fastadapter.FastAdapter +import com.mikepenz.fastadapter.IItem +import com.mikepenz.fastadapter.items.AbstractItem + +/** + * Created by Allan Wang on 2017-06-27. + */ +class LibraryIItem(val lib: Library +) : AbstractItem<LibraryIItem, LibraryIItem.ViewHolder>(), ThemableIItem by ThemableIItemDelegate() { + + companion object { + @JvmStatic fun bindClickEvents(fastAdapter: FastAdapter<IItem<*, *>>) { + fastAdapter.withOnClickListener { v, _, item, _ -> + if (item !is LibraryIItem) false + else { + val c = v.context + with(item.lib) { + c.startLink(libraryWebsite, repositoryLink, authorWebsite) + } + true + } + } + } + } + + override fun getType(): Int = R.id.kau_item_library + + override fun getLayoutRes(): Int = R.layout.kau_iitem_library + + override fun isSelectable(): Boolean = false + + override fun bindView(holder: ViewHolder, payloads: MutableList<Any>?) { + super.bindView(holder, payloads) + with(holder) { + name.text = lib.libraryName + creator.text = lib.author + description.text = if (lib.libraryDescription.isBlank()) lib.libraryDescription + else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + Html.fromHtml(lib.libraryDescription, Html.FROM_HTML_MODE_LEGACY) + else Html.fromHtml(lib.libraryDescription) + bottomDivider.gone() + if (lib.libraryVersion?.isNotBlank() ?: false) { + bottomDivider.visible() + version.visible().text = lib.libraryVersion + } + if (lib.license?.licenseName?.isNotBlank() ?: false) { + bottomDivider.visible() + license.visible().text = lib.license?.licenseName + } + bindTextColor(name, creator) + bindTextColorSecondary(description) + bindAccentColor(license, version) + bindDividerColor(divider, bottomDivider) + bindBackgroundRipple(card) + } + } + + override fun unbindView(holder: ViewHolder) { + super.unbindView(holder) + with(holder) { + name.text = null + creator.text = null + description.text = null + bottomDivider.gone() + version.gone().text = null + license.gone().text = null + } + } + + override fun getViewHolder(v: View): ViewHolder = ViewHolder(v) + + class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { + val card: CardView by bindView(R.id.lib_item_card) + val name: TextView by bindView(R.id.lib_item_name) + val creator: TextView by bindView(R.id.lib_item_author) + val description: TextView by bindView(R.id.lib_item_description) + val version: TextView by bindView(R.id.lib_item_version) + val license: TextView by bindView(R.id.lib_item_license) + val divider: View by bindView(R.id.lib_item_top_divider) + val bottomDivider: View by bindView(R.id.lib_item_bottom_divider) + } + +}
\ No newline at end of file diff --git a/about/src/main/res/layout/kau_about_section_libraries.xml b/about/src/main/res/layout/kau_about_section_libraries.xml new file mode 100644 index 0000000..c14225e --- /dev/null +++ b/about/src/main/res/layout/kau_about_section_libraries.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/about_library_container" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <TextView + android:id="@+id/about_library_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="@dimen/kau_activity_horizontal_margin" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.5" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <android.support.v7.widget.RecyclerView + android:id="@+id/about_library_recycler" + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/about_library_title" /> + +</android.support.constraint.ConstraintLayout> diff --git a/about/src/main/res/layout/kau_about_section_main.xml b/about/src/main/res/layout/kau_about_section_main.xml new file mode 100644 index 0000000..40d8dfb --- /dev/null +++ b/about/src/main/res/layout/kau_about_section_main.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:showIn="@layout/kau_activity_about"> + + <android.support.constraint.ConstraintLayout + android:id="@+id/about_main_container" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ca.allanwang.kau.views.CutoutView + android:id="@+id/about_main_cutout" + android:layout_width="0dp" + android:layout_height="@dimen/kau_about_header_height" + android:minHeight="@dimen/kau_about_header_height" + app:foregroundColor="?android:colorAccent" + app:heightPercentageToScreen="0.5" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <FrameLayout + android:id="@+id/about_main_bottom_container" + android:layout_width="0dp" + android:layout_height="2000dp" + android:background="?android:attr/colorBackground" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/about_main_cutout"> + + <TextView + android:id="@+id/about_main_bottom_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:layout_margin="@dimen/activity_horizontal_margin" /> + + </FrameLayout> + + </android.support.constraint.ConstraintLayout> + +</android.support.v4.widget.NestedScrollView> diff --git a/about/src/main/res/layout/kau_activity_about.xml b/about/src/main/res/layout/kau_activity_about.xml new file mode 100644 index 0000000..3d1f9ab --- /dev/null +++ b/about/src/main/res/layout/kau_activity_about.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/about_draggable_frame" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:dragDismissDistance="@dimen/kau_drag_dismiss_distance" + app:dragDismissScale="0.95" + tools:context=".ui.about.AboutActivityBase"> + + <android.support.v4.view.ViewPager + android:id="@+id/about_pager" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <ca.allanwang.kau.ui.widgets.InkPageIndicator + android:id="@+id/about_indicator" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top|center_horizontal" + android:layout_marginTop="@dimen/kau_padding_normal" + app:currentPageIndicatorColor="@color/kau_about_page_indicator_dark_selected" + app:pageIndicatorColor="@color/kau_about_page_indicator_dark" /> + +</ca.allanwang.kau.ui.widgets.ElasticDragDismissFrameLayout> diff --git a/about/src/main/res/layout/kau_iitem_cutout.xml b/about/src/main/res/layout/kau_iitem_cutout.xml new file mode 100644 index 0000000..b3a841e --- /dev/null +++ b/about/src/main/res/layout/kau_iitem_cutout.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<ca.allanwang.kau.ui.views.CutoutView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/kau_cutout" + android:layout_width="match_parent" + android:layout_height="@dimen/kau_about_header_height" + android:minHeight="@dimen/kau_about_header_height" + app:foregroundColor="?android:colorAccent" + app:heightPercentageToScreen="0.5" />
\ No newline at end of file diff --git a/about/src/main/res/layout/kau_iitem_library.xml b/about/src/main/res/layout/kau_iitem_library.xml new file mode 100644 index 0000000..1c3de5c --- /dev/null +++ b/about/src/main/res/layout/kau_iitem_library.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/lib_item_card" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/kau_padding_normal" + android:background="?android:selectableItemBackground" + android:clickable="true"> + + <android.support.constraint.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="@dimen/kau_padding_normal" + android:paddingEnd="@dimen/kau_padding_normal" + android:paddingStart="@dimen/kau_padding_normal" + android:paddingTop="@dimen/kau_padding_normal"> + + <android.support.constraint.Guideline + android:id="@+id/lib_g_m_v" + android:layout_width="1dp" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent="0.5" /> + + <TextView + android:id="@+id/lib_item_name" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:ellipsize="end" + android:gravity="start" + android:maxLines="1" + android:textSize="@dimen/textSizeLarge_openSource" + android:textStyle="normal" + app:layout_constraintEnd_toStartOf="@id/lib_g_m_v" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:text="Library name" /> + + <TextView + android:id="@+id/lib_item_author" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="2dp" + android:gravity="end" + android:maxLines="2" + android:textSize="@dimen/textSizeSmall_openSource" + android:textStyle="normal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/lib_g_m_v" + app:layout_constraintTop_toTopOf="parent" + tools:text="Author" /> + + <android.support.constraint.Barrier + android:id="@+id/lib_item_top_divider" + android:layout_width="wrap_content" + android:layout_height="1px" + android:layout_marginTop="@dimen/kau_spacing_micro" + app:barrierDirection="bottom" + app:constraint_referenced_ids="lib_item_name,lib_item_author" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + <TextView + android:id="@+id/lib_item_description" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:maxLines="20" + android:paddingBottom="@dimen/kau_spacing_normal" + android:paddingTop="@dimen/kau_spacing_normal" + android:textSize="@dimen/textSizeSmall_openSource" + android:textStyle="normal" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/lib_item_top_divider" + tools:text="Description" /> + + <View + android:id="@+id/lib_item_bottom_divider" + android:layout_width="match_parent" + android:layout_height="1px" + android:layout_marginTop="@dimen/kau_spacing_micro" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/lib_item_description" /> + + <TextView + android:id="@+id/lib_item_version" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/kau_spacing_normal" + android:layout_marginTop="@dimen/kau_spacing_micro" + android:layout_weight="1" + android:gravity="start" + android:maxLines="1" + android:textSize="@dimen/textSizeSmall_openSource" + android:textStyle="normal" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@id/lib_g_m_v" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/lib_item_bottom_divider" + tools:text="Version" /> + + <TextView + android:id="@+id/lib_item_license" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/kau_spacing_normal" + android:layout_marginTop="@dimen/kau_spacing_micro" + android:layout_weight="1" + android:gravity="end" + android:maxLines="1" + android:textSize="@dimen/textSizeSmall_openSource" + android:textStyle="normal" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@id/lib_g_m_v" + app:layout_constraintTop_toBottomOf="@id/lib_item_bottom_divider" + tools:text="License" /> + + </android.support.constraint.ConstraintLayout> + +</android.support.v7.widget.CardView>
\ No newline at end of file diff --git a/about/src/main/res/transition/kau_about_return_downward.xml b/about/src/main/res/transition/kau_about_return_downward.xml new file mode 100644 index 0000000..b040b1b --- /dev/null +++ b/about/src/main/res/transition/kau_about_return_downward.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<transitionSet + xmlns:android="http://schemas.android.com/apk/res/android" + android:transitionOrdering="together" + android:interpolator="@android:interpolator/fast_out_linear_in"> + + <slide + android:slideEdge="bottom" + android:duration="400"> + <targets> + <target android:excludeId="@android:id/navigationBarBackground" /> + <target android:excludeId="@android:id/statusBarBackground" /> + </targets> + </slide> + + <fade + android:startDelay="200" + android:duration="200"> + <targets> + <target android:targetId="@id/about_indicator" /> + <!--<target android:targetId="@id/libraries_intro" />--> + <!--<target android:targetId="@id/libs_list_background" />--> + </targets> + </fade> + + <fade android:duration="400"> + <targets> + <target android:targetId="@android:id/navigationBarBackground" /> + <target android:targetId="@android:id/statusBarBackground" /> + </targets> + </fade> + +</transitionSet> diff --git a/about/src/main/res/transition/kau_about_return_upwards.xml b/about/src/main/res/transition/kau_about_return_upwards.xml new file mode 100644 index 0000000..64b3f5e --- /dev/null +++ b/about/src/main/res/transition/kau_about_return_upwards.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2015 Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<transitionSet + xmlns:android="http://schemas.android.com/apk/res/android" + android:transitionOrdering="together" + android:interpolator="@android:interpolator/fast_out_linear_in"> + + <slide + android:slideEdge="top" + android:duration="400"> + <targets> + <target android:excludeId="@android:id/navigationBarBackground" /> + <target android:excludeId="@android:id/statusBarBackground" /> + </targets> + </slide> + + <fade + android:startDelay="200" + android:duration="200"> + <targets> + <target android:targetId="@id/about_indicator" /> + <!--<target android:targetId="@id/libraries_intro" />--> + <!--<target android:targetId="@id/libs_list_background" />--> + + </targets> + </fade> + + <fade android:duration="400"> + <targets> + <target android:targetId="@android:id/navigationBarBackground" /> + <target android:targetId="@android:id/statusBarBackground" /> + </targets> + </fade> + +</transitionSet> diff --git a/about/src/main/res/values/styles.xml b/about/src/main/res/values/styles.xml new file mode 100644 index 0000000..59b2470 --- /dev/null +++ b/about/src/main/res/values/styles.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <style name="Kau.Translucent.About"> + <item name="android:windowEnterTransition">@transition/kau_enter_slide_top</item> + <item name="android:windowReturnTransition">@transition/kau_about_return_upwards</item> + </style> + +</resources>
\ No newline at end of file diff --git a/about/src/test/java/ca/allanwang/kau/ExampleUnitTest.java b/about/src/test/java/ca/allanwang/kau/ExampleUnitTest.java new file mode 100644 index 0000000..a29b447 --- /dev/null +++ b/about/src/test/java/ca/allanwang/kau/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package ca.allanwang.kau; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +}
\ No newline at end of file |