Improve UI

This commit is contained in:
Admin
2020-02-01 13:26:05 +02:00
parent 05b0d34c1f
commit 97ef9ddb48
30 changed files with 253 additions and 72 deletions

View File

@@ -9,7 +9,7 @@ data class Manga(
val title: String,
val localizedTitle: String? = null,
val url: String,
val rating: Float = -1f, //normalized value [0..1] or -1
val rating: Float = NO_RATING, //normalized value [0..1] or -1
val coverUrl: String,
val largeCoverUrl: String? = null,
val summary: String,
@@ -18,4 +18,10 @@ data class Manga(
val state: MangaState? = null,
val chapters: List<MangaChapter>? = null,
val source: MangaSource
) : Parcelable
) : Parcelable {
companion object {
const val NO_RATING = -1f
}
}

View File

@@ -40,7 +40,7 @@ class ReadmangaRepository(loaderContext: MangaLoaderContext) : MangaRepository(l
?.substringBefore(' ')
?.toFloatOrNull()
?.div(10f)
} ?: -1f,
} ?: Manga.NO_RATING,
tags = safe {
descDiv.selectFirst("div.tile-info")
?.select("a.element-link")

View File

@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.ui.common
import android.content.Context
import android.content.SharedPreferences
import android.os.Parcelable
import androidx.annotation.IdRes
@@ -21,4 +22,13 @@ abstract class BaseFragment(@LayoutRes contentLayoutId: Int) :
fun <T : Parcelable> arg(name: String) = ParcelableArgumentDelegate<T>(name)
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) = Unit
open fun getTitle(): CharSequence? = null
override fun onAttach(context: Context) {
super.onAttach(context)
getTitle()?.let {
activity?.title = it
}
}
}

View File

@@ -4,13 +4,15 @@ import android.content.res.Configuration
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.fragment.app.Fragment
import com.google.android.material.navigation.NavigationView
import kotlinx.android.synthetic.main.activity_main.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.ui.common.BaseActivity
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
class MainActivity : BaseActivity() {
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var drawerToggle: ActionBarDrawerToggle
@@ -18,21 +20,23 @@ class MainActivity : BaseActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
drawerToggle = ActionBarDrawerToggle(this, drawer, toolbar, R.string.open_menu, R.string.close_menu)
drawerToggle =
ActionBarDrawerToggle(this, drawer, toolbar, R.string.open_menu, R.string.close_menu)
drawer.addDrawerListener(drawerToggle)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true)
navigationView.setNavigationItemSelectedListener(this)
if (!supportFragmentManager.isStateSaved) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MangaListFragment.newInstance(MangaSource.READMANGA_RU))
.commit()
setPrimaryFragment(MangaListFragment.newInstance(MangaSource.READMANGA_RU))
}
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
drawerToggle.syncState()
initSideMenu(MangaSource.values().asList())
}
override fun onConfigurationChanged(newConfig: Configuration) {
@@ -43,4 +47,33 @@ class MainActivity : BaseActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return drawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
if (item.groupId == R.id.group_remote_sources) {
val source = MangaSource.values().getOrNull(item.itemId) ?: return false
setPrimaryFragment(MangaListFragment.newInstance(source))
} else when (item.itemId) {
R.id.nav_history -> Unit
R.id.nav_favourites -> Unit
R.id.nav_local_storage -> Unit
else -> return false
}
drawer.closeDrawers()
return true
}
private fun initSideMenu(remoteSources: List<MangaSource>) {
val submenu = navigationView.menu.findItem(R.id.nav_remote_sources).subMenu
submenu.removeGroup(R.id.group_remote_sources)
remoteSources.forEachIndexed { index, source ->
submenu.add(R.id.group_remote_sources, source.ordinal, index, source.title)
}
submenu.setGroupCheckable(R.id.group_remote_sources, true, true)
}
private fun setPrimaryFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit()
}
}

View File

@@ -13,6 +13,7 @@ import org.koitharu.kotatsu.ui.common.BaseFragment
class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsView {
@Suppress("unused")
private val presenter by moxyPresenter { (activity as MangaDetailsActivity).presenter }
private lateinit var adapter: ChaptersAdapter

View File

@@ -10,20 +10,24 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.ui.common.BaseFragment
import org.koitharu.kotatsu.utils.ext.setChips
import kotlin.math.roundToInt
class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetailsView {
@Suppress("unused")
private val presenter by moxyPresenter { (activity as MangaDetailsActivity).presenter }
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
}
override fun onMangaUpdated(manga: Manga) {
imageView_cover.load(manga.largeCoverUrl ?: manga.coverUrl)
textView_title.text = manga.title
textView_subtitle.text = manga.localizedTitle
textView_description.text = manga.description
if (manga.rating == Manga.NO_RATING) {
ratingBar.isVisible = false
} else {
ratingBar.progress = (ratingBar.max * manga.rating).roundToInt()
ratingBar.isVisible = true
}
chips_tags.setChips(manga.tags) {
create(
text = it.title,

View File

@@ -1,6 +1,8 @@
package org.koitharu.kotatsu.ui.main.list
import android.annotation.SuppressLint
import android.view.ViewGroup
import androidx.core.view.isVisible
import coil.api.load
import coil.request.RequestDisposable
import kotlinx.android.synthetic.main.item_manga_list_details.*
@@ -8,11 +10,13 @@ import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.ui.common.list.BaseViewHolder
import org.koitharu.kotatsu.utils.ext.textAndVisible
import kotlin.math.roundToInt
class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder<Manga>(parent, R.layout.item_manga_list_details) {
private var coverRequest: RequestDisposable? = null
@SuppressLint("SetTextI18n")
override fun onBind(data: Manga) {
coverRequest?.dispose()
textView_title.text = data.title
@@ -20,5 +24,14 @@ class MangaListDetailsHolder(parent: ViewGroup) : BaseViewHolder<Manga>(parent,
coverRequest = imageView_cover.load(data.coverUrl) {
crossfade(true)
}
if(data.rating == Manga.NO_RATING) {
textView_rating.isVisible = false
} else {
textView_rating.text = "${(data.rating * 10).roundToInt()}/10"
textView_rating.isVisible = true
}
textView_tags.text = data.tags.joinToString(", ") {
it.title
}
}
}

View File

@@ -100,6 +100,10 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
swipeRefreshLayout.isEnabled = !progressBar.isVisible
}
override fun getTitle(): CharSequence? {
return source.title
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
when(key) {
getString(R.string.key_list_mode) -> initListMode(settings.listMode)
@@ -119,8 +123,8 @@ class MangaListFragment : BaseFragment(R.layout.fragment_list), MangaListView,
}
recyclerView.adapter = adapter
recyclerView.addItemDecoration(when(mode) {
ListMode.DETAILED_LIST,
ListMode.LIST -> DividerItemDecoration(ctx, RecyclerView.VERTICAL)
ListMode.DETAILED_LIST,
ListMode.GRID -> SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing))
})
adapter.notifyDataSetChanged()

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108"
android:tint="#0D47A1">
<group android:scaleX="0.40188664"
android:scaleY="0.40188664"
android:translateX="32.90095"
android:translateY="18.7272">
<group android:translateY="139.39206">
<path android:pathData="M83.796875,-0L105.6875,-0L60.765625,-55.828125L103.09375,-101L82.078125,-101L32.25,-49.1875L32.25,-101L13.53125,-101L13.53125,-0L32.25,-0L32.25,-25.8125L48.234375,-42.265625L83.796875,-0Z"
android:fillColor="#0D47A1"/>
</group>
</group>
</vector>

View File

@@ -0,0 +1,13 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorAccent"
android:pathData="M12,15.4l-3.76,2.27l1,-4.28l-3.32,-2.88l4.38,-0.38l1.7,-4.03l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28z" />
<path
android:fillColor="?android:textColorPrimary"
android:pathData="M22,9.24l-7.19,-0.62L12,2L9.19,8.63L2,9.24l5.46,4.73L5.82,21L12,17.27L18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27l1,-4.28l-3.32,-2.88l4.38,-0.38L12,6.1l1.71,4.04l4.38,0.38l-3.32,2.88l1,4.28L12,15.4z" />
</vector>

View File

@@ -37,9 +37,11 @@
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/view_nav_header"
app:menu="@menu/nav_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.core.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"
@@ -38,22 +39,32 @@
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="?android:textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintEnd_toEndOf="@id/textView_title"
app:layout_constraintStart_toStartOf="@id/textView_title"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem" />
<RatingBar
android:id="@+id/ratingBar"
style="@style/Widget.AppCompat.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:isIndicator="true"
android:max="100"
tools:progress="70"
app:layout_constraintStart_toStartOf="@id/textView_title"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="imageView_cover, textView_subtitle" />
app:constraint_referenced_ids="imageView_cover, textView_subtitle, ratingBar" />
<com.google.android.material.chip.ChipGroup
android:id="@+id/chips_tags"
@@ -61,18 +72,18 @@
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:padding="6dp"
app:lineSpacing="2dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_title" />
app:layout_constraintTop_toBottomOf="@id/barrier_title"
app:lineSpacing="2dp" />
<TextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:justificationMode="inter_word"
android:padding="12dp"
android:lineSpacingMultiplier="1.2"
android:padding="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags"

View File

@@ -1,43 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/manga_list_details_item_height"
android:background="?selectableItemBackground"
android:orientation="horizontal">
android:layout_height="@dimen/manga_list_details_item_height">
<org.koitharu.kotatsu.ui.common.widgets.CoverImageView
android:id="@+id/imageView_cover"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" />
<LinearLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:orientation="vertical"
android:paddingTop="12dp"
android:paddingStart="16dp"
android:paddingEnd="16dp">
android:layout_height="match_parent">
<org.koitharu.kotatsu.ui.common.widgets.CoverImageView
android:id="@+id/imageView_cover"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:orientation="vertical" />
<TextView
android:id="@+id/textView_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="6dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="6dp"
android:layout_toEndOf="@id/imageView_cover"
android:ellipsize="end"
android:lines="2"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" />
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
tools:text="@tools:sample/lorem[6]" />
<TextView
android:id="@+id/textView_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/divider"
android:layout_below="@id/textView_title"
android:layout_marginStart="6dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="6dp"
android:layout_marginBottom="6dp"
android:layout_toEndOf="@id/imageView_cover"
android:ellipsize="end"
android:lines="1"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
android:textColor="?android:textColorSecondary" />
android:textColor="?android:textColorSecondary"
tools:text="@tools:sample/lorem[6]" />
</LinearLayout>
<TextView
android:id="@+id/textView_tags"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/divider"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp"
android:layout_toStartOf="@id/textView_rating"
android:layout_toEndOf="@id/imageView_cover"
android:ellipsize="none"
android:gravity="center_vertical"
android:requiresFadingEdge="horizontal"
android:singleLine="true" />
</LinearLayout>
<TextView
android:id="@+id/textView_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:drawableStart="@drawable/ic_star_rating"
android:drawablePadding="4dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
tools:text="10/10" />
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_above="@id/textView_rating"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@id/imageView_cover"
android:background="?android:listDivider" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="92dp">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:listDivider"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_local_storage"
android:icon="@drawable/ic_storage"
@@ -15,22 +16,22 @@
android:title="@string/history" />
</group>
<group android:id="@+id/group_menu">
<item
android:id="@+id/nav_remote_sources"
android:title="@string/remote_sources">
<menu>
<group
android:id="@+id/group_remote_sources"
android:checkableBehavior="single" />
</menu>
</item>
<group
android:id="@+id/group1"
android:checkableBehavior="none">
<item
android:id="@+id/nav_test"
android:title="Test" />
android:id="@+id/nav_action_settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings" />
</group>
<!--
<item android:title="Title 1">
<menu>
<item
android:id="@+id/nav_item_six"
android:icon="@drawable/ic_drafts_black_24dp"
android:title="Item 6" />
<item
android:id="@+id/nav_item_seven"
android:icon="@drawable/ic_drafts_black_24dp"
android:title="Item 7" />
</menu>
</item>-->
</menu>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon
xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon
xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
<color name="colorPrimary">#0288D1</color>
<color name="colorPrimaryDark">#0D47A1</color>
<color name="colorAccent">#F4511E</color>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -13,4 +13,6 @@
<string name="detailed_list">Detailed list</string>
<string name="grid">Grid</string>
<string name="list_mode">List mode</string>
<string name="settings">Settings</string>
<string name="remote_sources">Remote sources</string>
</resources>