migrate to ViewPager2

This commit is contained in:
Milos Kozak 2020-04-25 21:52:20 +02:00
parent edcc95a5bc
commit 403c609319
6 changed files with 64 additions and 137 deletions

View file

@ -123,6 +123,7 @@ tasks.matching { it instanceof Test }.all {
android { android {
compileSdkVersion 28 compileSdkVersion 28
ndkVersion "21.1.6352462"
defaultConfig { defaultConfig {
minSdkVersion 23 minSdkVersion 23

View file

@ -23,10 +23,8 @@ import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.drawerlayout.widget.DrawerLayout import androidx.viewpager2.widget.ViewPager2
import androidx.viewpager.widget.ViewPager import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.navigation.NavigationView
import com.google.android.material.tabs.TabLayout
import com.joanzapata.iconify.Iconify import com.joanzapata.iconify.Iconify
import com.joanzapata.iconify.fonts.FontAwesomeModule import com.joanzapata.iconify.fonts.FontAwesomeModule
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
@ -47,10 +45,10 @@ import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionChec
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.tabs.TabPageAdapter import info.nightscout.androidaps.utils.tabs.TabPageAdapter
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.LocaleHelper.update import info.nightscout.androidaps.utils.LocaleHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
@ -86,50 +84,44 @@ class MainActivity : NoSplashAppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Iconify.with(FontAwesomeModule()) Iconify.with(FontAwesomeModule())
update(applicationContext) LocaleHelper.update(applicationContext)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
supportActionBar?.setDisplayShowTitleEnabled(false) supportActionBar?.setDisplayShowTitleEnabled(false)
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setHomeButtonEnabled(true) supportActionBar?.setHomeButtonEnabled(true)
actionBarDrawerToggle = ActionBarDrawerToggle(this, drawer_layout, R.string.open_navigation, R.string.close_navigation).also { actionBarDrawerToggle = ActionBarDrawerToggle(this, main_drawer_layout, R.string.open_navigation, R.string.close_navigation).also {
drawer_layout.addDrawerListener(it) main_drawer_layout.addDrawerListener(it)
it.syncState() it.syncState()
} }
// initialize screen wake lock // initialize screen wake lock
processPreferenceChange(EventPreferenceChange(resourceHelper.gs(R.string.key_keep_screen_on))) processPreferenceChange(EventPreferenceChange(resourceHelper.gs(R.string.key_keep_screen_on)))
pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { main_pager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
checkPluginPreferences(pager) checkPluginPreferences(main_pager)
} }
override fun onPageScrollStateChanged(state: Int) {}
}) })
//Check here if loop plugin is disabled. Else check via constraints //Check here if loop plugin is disabled. Else check via constraints
if (!loopPlugin.isEnabled(PluginType.LOOP)) versionCheckerUtils.triggerCheckVersion() if (!loopPlugin.isEnabled(PluginType.LOOP)) versionCheckerUtils.triggerCheckVersion()
fabricPrivacy.setUserStats() fabricPrivacy.setUserStats()
setupTabs()
setupViews() setupViews()
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventRebuildTabs::class.java) .toObservable(EventRebuildTabs::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
update(applicationContext)
if (it.recreate) recreate() if (it.recreate) recreate()
else { else setupViews()
setupTabs()
setupViews()
}
setWakeLock() setWakeLock()
}) { fabricPrivacy.logException(it) } }) { fabricPrivacy::logException }
) )
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventPreferenceChange::class.java) .toObservable(EventPreferenceChange::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ processPreferenceChange(it) }) { fabricPrivacy.logException(it) } .subscribe({ processPreferenceChange(it) }) { fabricPrivacy::logException }
) )
if (!sp.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) { if (!sp.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) {
val intent = Intent(this, SetupWizardActivity::class.java) val intent = Intent(this, SetupWizardActivity::class.java)
@ -144,7 +136,7 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
} }
private fun checkPluginPreferences(viewPager: ViewPager) { private fun checkPluginPreferences(viewPager: ViewPager2) {
pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1 pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1
} }
@ -179,50 +171,46 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
private fun setupViews() { private fun setupViews() {
val pageAdapter = TabPageAdapter(supportFragmentManager, this) // Menu
val navigationView = findViewById<NavigationView>(R.id.navigation_view) val pageAdapter = TabPageAdapter(this)
navigationView.setNavigationItemSelectedListener { true } main_navigation_view.setNavigationItemSelectedListener { true }
val menu = navigationView.menu.also { it.clear() } val menu = main_navigation_view.menu.also { it.clear() }
for (p in activePlugin.pluginsList) { for (p in activePlugin.pluginsList) {
pageAdapter.registerNewFragment(p) pageAdapter.registerNewFragment(p)
if (p.hasFragment() && !p.isFragmentVisible() && p.isEnabled(p.pluginDescription.type) && !p.pluginDescription.neverVisible) { if (p.isEnabled() && p.hasFragment() && !p.isFragmentVisible() && !p.pluginDescription.neverVisible) {
val menuItem = menu.add(p.name) val menuItem = menu.add(p.name)
menuItem.isCheckable = true menuItem.isCheckable = true
menuItem.setOnMenuItemClickListener { menuItem.setOnMenuItemClickListener {
val intent = Intent(this, SingleFragmentActivity::class.java) val intent = Intent(this, SingleFragmentActivity::class.java)
intent.putExtra("plugin", activePlugin.pluginsList.indexOf(p)) intent.putExtra("plugin", activePlugin.pluginsList.indexOf(p))
startActivity(intent) startActivity(intent)
(findViewById<View>(R.id.drawer_layout) as DrawerLayout).closeDrawers() main_drawer_layout.closeDrawers()
true true
} }
} }
} }
val mPager = findViewById<ViewPager>(R.id.pager) main_pager.adapter = pageAdapter
mPager.adapter = pageAdapter checkPluginPreferences(main_pager)
//if (switchToLast)
// mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
checkPluginPreferences(mPager)
}
private fun setupTabs() { // Tabs
val viewPager = findViewById<ViewPager>(R.id.pager)
val normalTabs = findViewById<TabLayout>(R.id.tabs_normal)
normalTabs.setupWithViewPager(viewPager, true)
val compactTabs = findViewById<TabLayout>(R.id.tabs_compact)
compactTabs.setupWithViewPager(viewPager, true)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
if (sp.getBoolean(R.string.key_short_tabtitles, false)) { if (sp.getBoolean(R.string.key_short_tabtitles, false)) {
normalTabs.visibility = View.GONE tabs_normal.visibility = View.GONE
compactTabs.visibility = View.VISIBLE tabs_compact.visibility = View.VISIBLE
toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, resources.getDimension(R.dimen.compact_height).toInt()) toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, resources.getDimension(R.dimen.compact_height).toInt())
TabLayoutMediator(tabs_compact, main_pager) { tab, position ->
tab.text = (main_pager.adapter as TabPageAdapter).getPluginAt(position).nameShort
}.attach()
} else { } else {
normalTabs.visibility = View.VISIBLE tabs_normal.visibility = View.VISIBLE
compactTabs.visibility = View.GONE tabs_compact.visibility = View.GONE
val typedValue = TypedValue() val typedValue = TypedValue()
if (theme.resolveAttribute(R.attr.actionBarSize, typedValue, true)) { if (theme.resolveAttribute(R.attr.actionBarSize, typedValue, true)) {
toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT, toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT,
TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)) TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics))
} }
TabLayoutMediator(tabs_normal, main_pager) { tab, position ->
tab.text = (main_pager.adapter as TabPageAdapter).getPluginAt(position).name
}.attach()
} }
} }
@ -260,7 +248,7 @@ class MainActivity : NoSplashAppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu) menuInflater.inflate(R.menu.menu_main, menu)
pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences) pluginPreferencesMenuItem = menu.findItem(R.id.nav_plugin_preferences)
checkPluginPreferences(findViewById(R.id.pager)) checkPluginPreferences(main_pager)
return true return true
} }
@ -314,8 +302,7 @@ class MainActivity : NoSplashAppCompatActivity() {
} }
R.id.nav_plugin_preferences -> { R.id.nav_plugin_preferences -> {
val viewPager = findViewById<ViewPager>(R.id.pager) val plugin = (main_pager.adapter as TabPageAdapter).getPluginAt(main_pager.currentItem)
val plugin = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem)
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, Runnable { protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, Runnable {
val i = Intent(this, PreferencesActivity::class.java) val i = Intent(this, PreferencesActivity::class.java)
i.putExtra("id", plugin.preferencesId) i.putExtra("id", plugin.preferencesId)

View file

@ -1,84 +0,0 @@
package info.nightscout.androidaps.tabs;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import android.view.ViewGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 30.05.2016.
*/
public class TabPageAdapter extends FragmentPagerAdapter {
ArrayList<PluginBase> visibleFragmentList = new ArrayList<>();
Context context;
private static Logger log = StacktraceLoggerWrapper.getLogger(L.CORE);
public TabPageAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
@Nullable
public Fragment getItem(int position) {
//Fragment fragment = (Fragment) visibleFragmentList.get(position);
return Fragment.instantiate(context, visibleFragmentList.get(position).getPluginDescription().getFragmentClass());
}
public PluginBase getPluginAt(int position) {
return visibleFragmentList.get(position);
}
@Override
public void finishUpdate(ViewGroup container) {
try {
super.finishUpdate(container);
} catch (NullPointerException nullPointerException) {
System.out.println("Catch the NullPointerException in FragmentStatePagerAdapter.finishUpdate");
} catch (IllegalStateException e) {
log.error("Unhandled exception", e);
}
}
@Override
public CharSequence getPageTitle(int position) {
if (SP.getBoolean(R.string.key_short_tabtitles, false)) {
return visibleFragmentList.get(position).getNameShort();
}
return visibleFragmentList.get(position).getName();
}
@Override
public int getCount() {
return visibleFragmentList.size();
}
public void registerNewFragment(PluginBase plugin) {
if (plugin.hasFragment() && plugin.isFragmentVisible()) {
visibleFragmentList.add(plugin);
notifyDataSetChanged();
}
}
@Override
public long getItemId(int position) {
return System.identityHashCode(visibleFragmentList.get(position));
}
}

View file

@ -0,0 +1,24 @@
package info.nightscout.androidaps.utils.tabs
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import info.nightscout.androidaps.interfaces.PluginBase
import java.util.*
class TabPageAdapter(private val activity: AppCompatActivity) : FragmentStateAdapter(activity) {
private val visibleFragmentList = ArrayList<PluginBase>()
override fun getItemCount(): Int = visibleFragmentList.size
override fun createFragment(position: Int): Fragment =
activity.supportFragmentManager.fragmentFactory.instantiate(ClassLoader.getSystemClassLoader(), visibleFragmentList[position].pluginDescription.fragmentClass)
fun getPluginAt(position: Int): PluginBase = visibleFragmentList[position]
fun registerNewFragment(plugin: PluginBase) {
if (plugin.hasFragment() && plugin.isFragmentVisible()) {
visibleFragmentList.add(plugin)
}
}
}

View file

@ -36,18 +36,18 @@
</androidx.appcompat.widget.Toolbar> </androidx.appcompat.widget.Toolbar>
<androidx.drawerlayout.widget.DrawerLayout <androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout" android:id="@+id/main_drawer_layout"
android:layout_weight="1" android:layout_weight="1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp"> android:layout_height="0dp">
<androidx.viewpager.widget.ViewPager <androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager" android:id="@+id/main_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<com.google.android.material.navigation.NavigationView <com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view" android:id="@+id/main_navigation_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
app:itemBackground="?selectableItemBackground" app:itemBackground="?selectableItemBackground"

View file

@ -1,7 +1,6 @@
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">