use fragments where it makes sense and add grid view with preference option

This commit is contained in:
2020-10-20 17:07:27 +03:00
parent c80ba8ade0
commit 6df9a750b5
18 changed files with 739 additions and 425 deletions
+6 -7
View File
@@ -13,22 +13,21 @@
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/NPSTheme"> android:theme="@style/NPSTheme">
<activity android:name=".activities.SplashActivity" android:theme="@style/NPSTheme.Splash"> <activity android:name=".activities.SplashActivity" android:theme="@style/NPSTheme.Splash">
<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>
</activity> </activity>
<activity <activity android:name=".activities.MainActivity"
android:name=".activities.SettingsActivity" android:configChanges="screenSize|screenLayout|keyboardHidden">
android:label="@string/title_activity_settings" </activity>
android:parentActivityName=".activities.MainActivity"/>
<activity android:name=".activities.AppsListActivity" />
<activity <activity
android:name=".activities.SingleAppActivity" android:name=".activities.SingleAppActivity"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity" /> tools:ignore="LockedOrientationActivity"
android:parentActivityName=".activities.MainActivity" />
</application> </application>
</manifest> </manifest>
@@ -1,48 +0,0 @@
package com.illusionware.npsbrowser.activities
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.RecyclerTouchListener
import com.illusionware.npsbrowser.adapters.AppAdapter
import com.illusionware.npsbrowser.databinding.ActivityAppsListBinding
class AppsListActivity : BaseActivity() {
companion object {
lateinit var apps : ArrayList<AppData>
}
private lateinit var recyclerView: RecyclerView
private lateinit var viewAdapter: RecyclerView.Adapter<*>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityAppsListBinding.inflate(layoutInflater)
setContentView(binding.root)
viewAdapter = AppAdapter(apps, applicationContext)
recyclerView = binding.appsRecycler
recyclerView.apply {
layoutManager = LinearLayoutManager(applicationContext)
adapter = viewAdapter
recyclerView.addOnItemTouchListener(RecyclerTouchListener(applicationContext, recyclerView, object : RecyclerTouchListener.ClickListener {
override fun onClick(view: View?, position: Int) {
val myIntent = Intent(context, SingleAppActivity::class.java)
SingleAppActivity.app = apps[position]
startActivity(myIntent)
}
override fun onLongClick(view: View?, recyclerView: RecyclerView?, position: Int) {
Toast.makeText(applicationContext, "TODO: Long Click ", Toast.LENGTH_SHORT).show()
}
}
))
}
}
}
@@ -1,108 +1,39 @@
package com.illusionware.npsbrowser.activities package com.illusionware.npsbrowser.activities
import android.Manifest import android.os.Bundle
import android.app.Activity import android.view.MenuItem
import android.content.Intent import com.illusionware.npsbrowser.R
import android.content.pm.PackageManager import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment
import android.os.Bundle
import android.util.Log class MainActivity : BaseActivity() {
import android.view.Menu
import android.view.MenuItem override fun onCreate(savedInstanceState: Bundle?) {
import androidx.core.app.ActivityCompat super.onCreate(savedInstanceState)
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader setTheme(R.style.NPSTheme)
import com.illusionware.npsbrowser.AppData setContentView(R.layout.activity_main)
import com.illusionware.npsbrowser.R if (savedInstanceState == null) {
import com.illusionware.npsbrowser.databinding.ActivityMainBinding supportFragmentManager.beginTransaction()
import kotlinx.android.synthetic.main.appbar.* .replace(R.id.container, MainActivityFragment.newInstance())
import java.io.InputStream .commitNow()
}
class MainActivity : BaseActivity() { }
private val tsvReader = csvReader { override fun onOptionsItemSelected(item: MenuItem): Boolean {
charset = "UTF-8" when (item.itemId) {
quoteChar = '\\' android.R.id.home -> {
escapeChar = '\\' supportFragmentManager.popBackStack()
delimiter = '\t' return true
skipEmptyLine = true }
} }
return super.onOptionsItemSelected(item)
override fun onCreate(savedInstanceState: Bundle?) { }
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater) fun showUpButton() {
setContentView(binding.root) supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
setSupportActionBar(toolbar)
fun hideUpButton() {
binding.tsvChooserButton.setOnClickListener { supportActionBar!!.setDisplayHomeAsUpEnabled(false)
if (!isStoragePermissionGranted()) }
return@setOnClickListener
val intent = Intent(Intent.ACTION_GET_CONTENT).apply { }
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/tab-separated-values"
}
startActivityForResult(intent, 1)
}
}
override fun onCreateOptionsMenu(menu : Menu) : Boolean {
menuInflater.inflate(R.menu.toolbar_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_settings -> {
val settingsIntent = Intent(this, SettingsActivity::class.java)
startActivity(settingsIntent)
true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { uri ->
val inputStream: InputStream? = contentResolver.openInputStream(uri)
val entries : List<Map<String, String?>> = tsvReader.readAllWithHeader(inputStream!!)
val myIntent = Intent(this, AppsListActivity::class.java)
val apps = ArrayList<AppData>(entries.size)
entries.forEach { entry ->
if (entry["Name"].isNullOrEmpty()) {
return@forEach
}
val id = entry["Title ID"]
val region = entry["Region"]
val name = entry["Name"]
val link = entry["PKG direct link"]
val license = entry["zRIF"]
val contentID = entry["Content ID"]
val lastDateTime = entry["Last Modification Date"]
val fileSize = entry["File Size"]?.toLongOrNull()
val sha256 = entry["SHA256"]
val minFW = entry["Required FW"]
val app = AppData(id, region, name, link ?: "MISSING", license ?: "MISSING",
contentID ?: "MISSING", lastDateTime ?: "MISSING",
fileSize ?: 0, sha256 ?: "MISSING", minFW)
apps.add(app)
}
apps.sortBy { it.title }
AppsListActivity.apps = apps
startActivity(myIntent)
}
}
}
private fun isStoragePermissionGranted(): Boolean {
return if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v("perms", "Permission is granted")
true
} else {
Log.v("perms", "Permission is revoked")
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
false
}
}
}
@@ -1,35 +0,0 @@
package com.illusionware.npsbrowser.activities
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.databinding.SettingsActivityBinding
import kotlinx.android.synthetic.main.appbar.*
class SettingsActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = SettingsActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(toolbar)
supportFragmentManager
.beginTransaction()
.replace(
R.id.settings,
SettingsFragment()
)
.commit()
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false);
}
}
}
@@ -3,7 +3,6 @@ package com.illusionware.npsbrowser.activities
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import com.illusionware.npsbrowser.activities.mainactivity.MainActivity
class SplashActivity : BaseActivity() { class SplashActivity : BaseActivity() {
@@ -1,51 +1,72 @@
package com.illusionware.npsbrowser.adapters package com.illusionware.npsbrowser.adapters
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.illusionware.npsbrowser.AppData import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.R import com.illusionware.npsbrowser.R
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class AppAdapter(private val appsList: ArrayList<AppData>, val context : Context) : RecyclerView.Adapter<AppAdapter.ViewHolder>() { class AppAdapter(private val appsList: ArrayList<AppData>, val context : Context) : RecyclerView.Adapter<AppAdapter.ViewHolder>() {
private final val LIST_ITEM = 0
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { private final val GRID_ITEM = 1
var appTitle: TextView = view.findViewById(R.id.appTitle) var isSwitchView = true
var appRegion: TextView = view.findViewById(R.id.appRegion)
var appMinFW: TextView = view.findViewById(R.id.appMinFW) inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var appLastDate: TextView = view.findViewById(R.id.appLastDate) var appTitle: TextView = view.findViewById(R.id.appTitle)
} var appRegion: TextView = view.findViewById(R.id.appRegion)
var appMinFW: TextView = view.findViewById(R.id.appMinFW)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { var appLastDate: TextView = view.findViewById(R.id.appLastDate)
return ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)) }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
override fun onBindViewHolder(holder: ViewHolder, position: Int) { return if (viewType == LIST_ITEM) {
holder.appTitle.text = appsList[position].title ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false))
holder.appRegion.text = appsList[position].region } else {
holder.appMinFW.text = appsList[position].minFW ViewHolder( LayoutInflater.from(parent.context).inflate(R.layout.grid_item, parent, false))
holder.appMinFW.background = null; }
}
if (holder.appMinFW.text.isNotBlank()) {
val drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.rect_red, null) override fun getItemViewType(position: Int): Int {
holder.appMinFW.background = drawable; return if (isSwitchView) {
} LIST_ITEM
holder.appLastDate.text = appsList[position].lastDateTime } else {
} GRID_ITEM
}
override fun getItemCount(): Int { }
return appsList.size
} public fun toggleItemViewType(type: Int): Boolean {
isSwitchView = type == 0
fun updateData(apps: ArrayList<AppData>) { return isSwitchView
appsList.clear() }
notifyDataSetChanged()
appsList.addAll(apps) override fun onBindViewHolder(holder: ViewHolder, position: Int) {
notifyDataSetChanged() holder.appTitle.text = appsList[position].title
holder.appTitle.isSelected = true
} holder.appRegion.text = appsList[position].region
holder.appMinFW.text = appsList[position].minFW
holder.appMinFW.background = null;
if (holder.appMinFW.text.isNotBlank()) {
val drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.rect_red, null)
holder.appMinFW.background = drawable;
}
holder.appLastDate.text = appsList[position].lastDateTime
}
override fun getItemCount(): Int {
return appsList.size
}
fun updateData(apps: ArrayList<AppData>) {
appsList.clear()
notifyDataSetChanged()
appsList.addAll(apps)
notifyDataSetChanged()
}
} }
@@ -0,0 +1,65 @@
package com.illusionware.npsbrowser.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.PreferenceManager
import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.activities.BaseActivity
import com.illusionware.npsbrowser.activities.MainActivity
import com.illusionware.npsbrowser.fragments.mainactivity.MainActivityFragment
import kotlinx.android.synthetic.main.appbar.*
class SettingsFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (activity!!.supportFragmentManager.backStackEntryCount < 1) {
(activity as MainActivity?)?.showUpButton()
MainActivityFragment().recyclerView?.adapter = MainActivityFragment().viewAdapter
}
PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false);
activity?.supportFragmentManager
?.beginTransaction()
?.replace(
R.id.prefs,
SettingsFragment()
)
?.setTransition(TRANSIT_FRAGMENT_OPEN)
?.commit()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
activity?.title = resources.getString(R.string.title_activity_settings)
return inflater.inflate(R.layout.settings_fragment, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as BaseActivity?)!!.setSupportActionBar(toolbar)
(activity as BaseActivity?)!!.supportActionBar?.setDisplayHomeAsUpEnabled(true)
//viewModel = ViewModelProviders.of(this).get(MainActivity2ViewModel::class.java)
// TODO: Use the ViewModel
}
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
PreferenceManager.setDefaultValues(context, R.xml.root_preferences, false);
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
//(activity as BaseActivity?)!!.setSupportActionBar(toolbar)
super.onActivityCreated(savedInstanceState)
}
}
}
@@ -0,0 +1,218 @@
package com.illusionware.npsbrowser.fragments.mainactivity
import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.Toast
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProviders
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.illusionware.npsbrowser.AppData
import com.illusionware.npsbrowser.R
import com.illusionware.npsbrowser.RecyclerTouchListener
import com.illusionware.npsbrowser.activities.SingleAppActivity
import com.illusionware.npsbrowser.activities.MainActivity
import com.illusionware.npsbrowser.adapters.AppAdapter
import com.illusionware.npsbrowser.fragments.SettingsFragment
import kotlinx.android.synthetic.main.appbar.*
import java.io.InputStream
class MainActivityFragment : Fragment(), FragmentManager.OnBackStackChangedListener {
var recyclerView : RecyclerView? = null
var viewAdapter: AppAdapter? = null
companion object {
fun newInstance() = MainActivityFragment()
var apps : ArrayList<AppData>? = arrayListOf()
}
private val tsvReader = csvReader {
charset = "UTF-8"
quoteChar = '\\'
escapeChar = '\\'
delimiter = '\t'
skipEmptyLine = true
skipMissMatchedRow = true
}
private lateinit var viewModel: MainActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity?.supportFragmentManager?.addOnBackStackChangedListener(this);
setHasOptionsMenu(true)
}
override fun onBackStackChanged() {
// enable Up button only if there are entries on the backstack
if (requireActivity().supportFragmentManager.backStackEntryCount < 1) {
(activity as MainActivity?)?.hideUpButton()
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
activity?.title = resources.getString(R.string.app_name)
val view = inflater.inflate(R.layout.main_fragment, container, false)
recyclerView = view?.findViewById(R.id.appsRecycler)
if (apps != null) {
viewAdapter = AppAdapter(apps!!, requireContext())
}
viewAdapter?.notifyDataSetChanged()
val orientation = this.resources.configuration.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0")
if (isViewAsList == "0") {
viewAdapter?.toggleItemViewType(0)
recyclerView?.layoutManager = LinearLayoutManager(context)
viewAdapter?.notifyDataSetChanged()
} else {
viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2)
viewAdapter?.notifyDataSetChanged()
}
recyclerView?.adapter = viewAdapter
recyclerView?.addOnItemTouchListener(RecyclerTouchListener(requireContext(), recyclerView!!, object : RecyclerTouchListener.ClickListener {
override fun onClick(view: View?, position: Int) {
val myIntent = Intent(context, SingleAppActivity::class.java)
SingleAppActivity.app = apps!![position]
startActivity(myIntent)
}
override fun onLongClick(view: View?, recyclerView: RecyclerView?, position: Int) {
Toast.makeText(context, "TODO: Long Click ", Toast.LENGTH_SHORT).show()
}
}
))
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
(activity as MainActivity?)!!.setSupportActionBar(toolbar)
view?.findViewById<FloatingActionButton>(R.id.tsvChooserButton)?.setOnClickListener {
if (!isStoragePermissionGranted())
return@setOnClickListener
val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/tab-separated-values"
}
startActivityForResult(intent, 1)
}
viewModel = ViewModelProviders.of(this).get(MainActivityViewModel::class.java)
// TODO: Use the ViewModel
}
override fun onCreateOptionsMenu(menu : Menu, menuInflater : MenuInflater) {
menuInflater.inflate(R.menu.toolbar_main, menu)
super.onCreateOptionsMenu(menu, menuInflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_settings -> {
activity?.supportFragmentManager
?.beginTransaction()
?.replace(
R.id.container,
SettingsFragment()
)
?.addToBackStack("settings")
?.commit()
true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
resultData?.data?.also { uri ->
Log.d("file_location", uri.toString())
val inputStream: InputStream? = activity?.contentResolver?.openInputStream(uri)
val entries : List<Map<String, String?>> = tsvReader.readAllWithHeader(inputStream!!)
apps?.clear()
apps = ArrayList(entries.size)
entries.forEach { entry ->
if (entry["Name"].isNullOrEmpty()) {
return@forEach
}
val id = entry["Title ID"]
val region = entry["Region"]
val name = entry["Name"]
val link = entry["PKG direct link"]
val license = entry["zRIF"]
val contentID = entry["Content ID"]
var lastDateTime = entry["Last Modification Date"]
if (!lastDateTime.isNullOrEmpty()) {
lastDateTime = lastDateTime.substring(0, 10)
}
val fileSize = entry["File Size"]?.toLongOrNull()
val sha256 = entry["SHA256"]
val minFW = entry["Required FW"]
val app = AppData(id, region, name, link ?: "MISSING", license ?: "MISSING",
contentID ?: "MISSING", lastDateTime ?: "MISSING",
fileSize, sha256 ?: "MISSING", minFW)
apps?.add(app)
}
apps?.sortBy { it.title }
recyclerView = view?.findViewById(R.id.appsRecycler)
viewAdapter = AppAdapter(apps!!, requireContext())
val orientation = this.resources.configuration.orientation
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
val isViewAsList = prefs.getString("layout_type", "0")
if (isViewAsList == "0") {
viewAdapter?.toggleItemViewType(0)
recyclerView?.layoutManager = LinearLayoutManager(context)
viewAdapter?.notifyDataSetChanged()
} else {
viewAdapter?.toggleItemViewType(1)
recyclerView?.layoutManager = GridLayoutManager(context,
if (orientation == Configuration.ORIENTATION_LANDSCAPE) 4 else 2)
viewAdapter?.notifyDataSetChanged()
}
recyclerView?.adapter = viewAdapter
}
}
}
private fun isStoragePermissionGranted(): Boolean {
return if (checkSelfPermission(this.context!!, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v("perms", "Permission is granted")
true
} else {
Log.v("perms", "Permission is revoked")
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1)
false
}
}
}
@@ -0,0 +1,7 @@
package com.illusionware.npsbrowser.fragments.mainactivity
import androidx.lifecycle.ViewModel
class MainActivityViewModel : ViewModel() {
// TODO: Implement the ViewModel
}
@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/appsRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
tools:listitem="@layout/list_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
+7 -26
View File
@@ -1,26 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout 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"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".activities.MainActivity"> tools:context=".activities.MainActivity" />
<include layout="@layout/appbar" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/tsvChooserButton"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_marginStart="176dp"
android:layout_marginEnd="176dp"
android:layout_marginBottom="50dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_add_yellow_24dp"
app:fabCustomSize="52dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:maxImageSize="32dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
+115
View File
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.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:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="0dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="214dp"
app:cardBackgroundColor="@color/colorPrimary"
app:cardElevation="4dp"
app:cardUseCompatPadding="false"
app:contentPadding="15dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView2"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_games_black_24dp" />
<TextView
android:id="@+id/appTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:ellipsize="marquee"
android:enabled="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:singleLine="true"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textColor="@color/colorOnPrimary"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView2"
tools:text="App Title" />
<TextView
android:id="@+id/appRegion"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/rect_light_blue"
android:paddingStart="4dp"
android:paddingLeft="10dp"
android:paddingTop="4dp"
android:paddingEnd="4dp"
android:paddingRight="10dp"
android:paddingBottom="4dp"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="ASIA" />
<TextView
android:id="@+id/appMinFW"
android:layout_width="36dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginBottom="8dp"
android:background="@drawable/rect_red"
android:padding="4dp"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/appRegion"
tools:text="3.69" />
<TextView
android:id="@+id/appLastDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:padding="4dp"
android:textColor="@color/colorOnSecondary"
android:textSize="10sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:text="2018-04-22" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.cardview.widget.CardView>
+103 -99
View File
@@ -1,100 +1,104 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:padding="0dp"> android:padding="0dp">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:cardBackgroundColor="@color/colorPrimary" app:cardBackgroundColor="@color/colorPrimary"
app:cardElevation="4dp" app:cardElevation="4dp"
app:cardUseCompatPadding="false" app:cardUseCompatPadding="false"
app:contentPadding="15dp"> app:contentPadding="15dp">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<TextView <ImageView
android:id="@+id/appRegion" android:id="@+id/imageView"
android:layout_width="40dp" android:layout_width="62dp"
android:layout_height="wrap_content" android:layout_height="56dp"
android:layout_marginStart="24dp" android:contentDescription="app icon"
android:background="@drawable/rect_light_blue" app:layout_constraintBottom_toBottomOf="parent"
android:paddingStart="4dp" app:layout_constraintStart_toStartOf="parent"
android:paddingLeft="10dp" app:layout_constraintTop_toTopOf="parent"
android:paddingTop="4dp" app:srcCompat="@drawable/ic_games_black_24dp" />
android:paddingEnd="4dp"
android:paddingRight="10dp" <TextView
android:paddingBottom="4dp" android:id="@+id/appTitle"
android:textAlignment="center" android:layout_width="0dp"
android:textColor="@color/colorOnSecondary" android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginStart="24dp"
app:layout_constraintEnd_toStartOf="@+id/appMinFW" android:ellipsize="marquee"
app:layout_constraintStart_toEndOf="@+id/imageView" /> android:focusable="auto"
android:focusableInTouchMode="true"
<TextView android:marqueeRepeatLimit="marquee_forever"
android:id="@+id/appTitle" android:scrollHorizontally="true"
android:layout_width="0dp" android:singleLine="true"
android:layout_height="wrap_content" android:textAlignment="viewStart"
android:layout_marginStart="24dp" android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="marquee" android:textColor="@color/colorOnPrimary"
android:focusable="auto" android:textSize="18sp"
android:focusableInTouchMode="true" app:layout_constraintEnd_toEndOf="parent"
android:marqueeRepeatLimit="marquee_forever" app:layout_constraintStart_toEndOf="@+id/imageView"
android:scrollHorizontally="true" app:layout_constraintTop_toTopOf="parent"
android:singleLine="true" tools:text="App Title" />
android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceListItem" <TextView
android:textColor="@color/colorOnPrimary" android:id="@+id/appRegion"
android:textSize="18sp" android:layout_width="40dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/imageView" android:layout_marginStart="24dp"
app:layout_constraintTop_toTopOf="parent" /> android:background="@drawable/rect_light_blue"
android:paddingStart="4dp"
<ImageView android:paddingLeft="10dp"
android:id="@+id/imageView" android:paddingTop="4dp"
android:layout_width="62dp" android:paddingEnd="4dp"
android:layout_height="56dp" android:paddingRight="10dp"
android:contentDescription="game icon" android:paddingBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent" android:textAlignment="center"
app:layout_constraintStart_toStartOf="parent" android:textColor="@android:color/white"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:srcCompat="@drawable/ic_games_black_24dp" /> app:layout_constraintEnd_toStartOf="@+id/appMinFW"
app:layout_constraintStart_toEndOf="@+id/imageView"
<TextView tools:text="ASIA" />
android:id="@+id/appMinFW"
android:layout_width="40dp" <TextView
android:layout_height="wrap_content" android:id="@+id/appMinFW"
android:layout_marginStart="8dp" android:layout_width="40dp"
android:background="@drawable/rect_red" android:layout_height="wrap_content"
android:padding="4dp" android:layout_marginStart="8dp"
android:textAlignment="center" android:background="@drawable/rect_red"
android:textColor="@color/colorOnSecondary" android:padding="4dp"
app:layout_constraintBottom_toBottomOf="parent" android:textAlignment="center"
app:layout_constraintStart_toEndOf="@+id/appRegion" /> android:textColor="@android:color/white"
app:layout_constraintBottom_toBottomOf="parent"
<TextView app:layout_constraintStart_toEndOf="@+id/appRegion"
android:id="@+id/appLastDate" tools:text="3.69" />
android:layout_width="wrap_content"
android:layout_height="wrap_content" <TextView
android:padding="4dp" android:id="@+id/appLastDate"
android:textColor="@color/colorOnSecondary" android:layout_width="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" /> android:padding="4dp"
</androidx.constraintlayout.widget.ConstraintLayout> android:textColor="@color/colorOnSecondary"
app:layout_constraintBottom_toBottomOf="parent"
</androidx.cardview.widget.CardView> app:layout_constraintEnd_toEndOf="parent"
tools:text="2020-02-12" />
</LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
android:clipChildren="false"
tools:context=".fragments.mainactivity.MainActivityFragment">
<include layout="@layout/appbar" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/appsRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="2"
tools:listitem="@layout/grid_item" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/tsvChooserButton"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_marginBottom="40dp"
android:clickable="true"
android:focusable="true"
android:src="@drawable/ic_add_yellow_24dp"
app:fabCustomSize="52dp"
app:layout_anchor="@+id/appsRecycler"
app:layout_anchorGravity="bottom|center"
app:maxImageSize="32dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -1,14 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical">
<include layout="@layout/appbar" />
<FrameLayout
android:id="@+id/settings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/prefers"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false">
<include
android:id="@+id/include"
layout="@layout/appbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/prefs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/include">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+21 -13
View File
@@ -1,13 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string-array name="app_theme"> <string-array name="app_theme">
<item>Light</item> <item>Light</item>
<item>Dark</item> <item>Dark</item>
<item>Use System Default</item> <item>Use System Default</item>
</string-array> </string-array>
<string-array name="app_theme_val"> <string-array name="app_theme_val">
<item>0</item> <item>0</item>
<item>1</item> <item>1</item>
<item>2</item> <item>2</item>
</string-array> </string-array>
</resources> <string-array name="layout_type">
<item>List</item>
<item>Grid</item>
</string-array>
<string-array name="layout_type_val">
<item>0</item>
<item>1</item>
</string-array>
</resources>
+18 -11
View File
@@ -1,12 +1,19 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory android:title="Customization"> <PreferenceCategory android:title="Customization">
<com.illusionware.npsbrowser.ThemePreference <com.illusionware.npsbrowser.ThemePreference
android:defaultValue="2" android:defaultValue="2"
android:entries="@array/app_theme" android:entries="@array/app_theme"
android:entryValues="@array/app_theme_val" android:entryValues="@array/app_theme_val"
android:key="app_theme" android:key="app_theme"
android:title="Theme" /> android:title="Theme" />
</PreferenceCategory> <ListPreference
android:defaultValue="0"
android:entries="@array/layout_type"
android:entryValues="@array/layout_type_val"
android:key="layout_type"
android:title="Layout"
app:useSimpleSummaryProvider="true"/>
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>