From df3ec95190dd998b09170bd8f8582deef9a79a92 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Tue, 19 Jul 2016 01:04:16 -0400 Subject: [PATCH] Refactor UI Move Page hierarchy to vizlib in preparation for it maybe being useful on a phone app, too. Move watch app UI creation from MGVA to MainActivity --- .../acmetensortoys/watchviz/MainActivity.java | 19 +- .../watchviz/MainGridViewAdapter.java | 163 ++---------------- .../watchviz/vizlib/util/FragmentPage.java | 51 ++++++ .../watchviz/vizlib/util/Page.java | 42 +++++ .../util/ProgrammablePreferenceFragment.java | 27 +++ .../watchviz/vizlib/util/RendererPage.java | 45 +++++ 6 files changed, 202 insertions(+), 145 deletions(-) create mode 100644 vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/FragmentPage.java create mode 100644 vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/Page.java create mode 100644 vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/ProgrammablePreferenceFragment.java create mode 100644 vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/RendererPage.java diff --git a/app/src/main/java/com/acmetensortoys/watchviz/MainActivity.java b/app/src/main/java/com/acmetensortoys/watchviz/MainActivity.java index dd7cc5a..5845acc 100644 --- a/app/src/main/java/com/acmetensortoys/watchviz/MainActivity.java +++ b/app/src/main/java/com/acmetensortoys/watchviz/MainActivity.java @@ -39,6 +39,11 @@ import java.util.Date; import java.util.Locale; import com.acmetensortoys.watchviz.vizlib.AudioProvider; +import com.acmetensortoys.watchviz.vizlib.rendering.Grid; +import com.acmetensortoys.watchviz.vizlib.rendering.WholeMax; +import com.acmetensortoys.watchviz.vizlib.util.FragmentPage; +import com.acmetensortoys.watchviz.vizlib.util.Page; +import com.acmetensortoys.watchviz.vizlib.util.RendererPage; public class MainActivity extends WearableActivity { @@ -53,9 +58,21 @@ public class MainActivity extends WearableActivity private GridViewPager mGridView; + Page[][] pages = new Page[][] + { + {new RendererPage(Grid.class, "grid"), + FragmentPage.makeProgrammablePreferencePage(R.xml.pref_grid, "grid", "grid pref")}, + + {new RendererPage(WholeMax.class, "whole")}, + + /* {MainGridViewAdapter.makeProgrammablePreferencePage(R.xml.pref_grid, + MainGridViewAdapter.RENDERER_GLOBAL_SHARED_PREF_NAME, + "global")} */ + }; + private void createSurfaces() { Log.d("createSurfaces", "top"); - MainGridViewAdapter mgva = new MainGridViewAdapter(this, mAudioProvider, mDebugView); + MainGridViewAdapter mgva = new MainGridViewAdapter(this, mAudioProvider, mDebugView, pages); mGridView.setOnPageChangeListener(mgva); mGridView.setAdapter(mgva); // Fake the selection callback. Why doesn't this happen automatically? :( diff --git a/app/src/main/java/com/acmetensortoys/watchviz/MainGridViewAdapter.java b/app/src/main/java/com/acmetensortoys/watchviz/MainGridViewAdapter.java index d24e635..69624bc 100644 --- a/app/src/main/java/com/acmetensortoys/watchviz/MainGridViewAdapter.java +++ b/app/src/main/java/com/acmetensortoys/watchviz/MainGridViewAdapter.java @@ -16,157 +16,42 @@ along with this program. If not, see . */ -/* This file is responsible for navigation of the UI, through different renderers - and (eventually), their settings, as well as global preferences and all that. +/* This file is responsible for navigation of the UI; the Pages are constructed + * elsewhere, this thing just manages what's on the screen. Note that we expect + * views that need to know whether they're on screen to find out via some other + * callback; we don't do anything here. */ - package com.acmetensortoys.watchviz; import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.PreferenceFragment; -import android.support.wearable.view.FragmentGridPagerAdapter; import android.support.wearable.view.GridPagerAdapter; import android.support.wearable.view.GridViewPager; import android.util.Log; -import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import com.acmetensortoys.watchviz.vizlib.AudioCanvas; import com.acmetensortoys.watchviz.vizlib.AudioProvider; -import com.acmetensortoys.watchviz.vizlib.Rendering; -import com.acmetensortoys.watchviz.vizlib.rendering.Grid; -import com.acmetensortoys.watchviz.vizlib.rendering.WholeMax; +import com.acmetensortoys.watchviz.vizlib.util.Page; public class MainGridViewAdapter extends GridPagerAdapter - implements GridViewPager.OnPageChangeListener { + implements GridViewPager.OnPageChangeListener, Page.VizLibUI { private final Activity mAct; // Also a Context private final AudioProvider mAp; private final TextView mDv; private final Page[][] pages; - public MainGridViewAdapter(Activity a, AudioProvider ap, TextView dv) { + public MainGridViewAdapter(Activity a, AudioProvider ap, TextView dv, Page[][] pages) { mAct = a; mAp = ap; mDv = dv; - - Page gridPage = new RendererPage(Grid.class, - mAct.getSharedPreferences("grid",Context.MODE_PRIVATE)); - Page wholePage = new RendererPage(WholeMax.class, - mAct.getSharedPreferences("whole",Context.MODE_PRIVATE)); - - pages = new Page[][]{ - {gridPage, new FragmentPage(ProgrammablePreferenceFragment - .newInstance(R.xml.pref_grid, "grid"))}, - {wholePage } - }; + this.pages = pages; } /* All returned Objects are actually Pages so we know what to do with them later */ - private abstract static class InstantiatedPage { - abstract public boolean ownsview(View v); - abstract public void deinstantiate(MainGridViewAdapter m, ViewGroup g); - }; - private abstract static class Page { - public String title; - abstract public InstantiatedPage instantiate(MainGridViewAdapter m, ViewGroup g, int r, int c); - } - - /* Some Pages just contain View objects directly */ - private static class ViewInstantiatedPage extends InstantiatedPage { - private final View v; - public ViewInstantiatedPage(View v) { this.v = v; } - @Override - public boolean ownsview(View v2) { return v == v2; } - @Override - public void deinstantiate(MainGridViewAdapter m, ViewGroup g) { g.removeView(v); } - } - private static class RendererPage extends Page { - private final Class re; - private final SharedPreferences lsp; - public RendererPage(Class r, SharedPreferences lsp) { - this.re = r; - this.lsp = lsp; - this.title = r.getSimpleName(); - } - public InstantiatedPage instantiate(MainGridViewAdapter mgva, ViewGroup g, int r, int c) { - final SurfaceView sv = new SurfaceView(mgva.mAct); - final AudioCanvas ac = new AudioCanvas(r+"x"+c, sv, mgva.mAp); - final Rendering rend; - try { - rend = re.getConstructor(SharedPreferences.class, SharedPreferences.class) - .newInstance(lsp, - mgva.mAct.getPreferences(Context.MODE_PRIVATE)); - ac.setRendering(rend); - } catch (Exception e) { - throw new RuntimeException(e); - } - g.addView(sv, -1, - new ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - return new ViewInstantiatedPage(sv); - } - } - - /* And some manage Fragments; note that these require assistance from finishUpdate below */ - private FragmentTransaction mFT = null; - private static class FragmentInstantedPage extends InstantiatedPage { - private final Fragment f; - - public FragmentInstantedPage(Fragment f) { this.f = f; } - - @Override - public boolean ownsview(View v) { - return v == f.getView(); - } - - @Override - public void deinstantiate(MainGridViewAdapter m, ViewGroup g) { - m.startFragmentTransaction().remove(f); - } - } - private static class FragmentPage extends Page { - private final Fragment f; - public FragmentPage(Fragment f) { this.f = f; } - - @Override - public InstantiatedPage instantiate(MainGridViewAdapter m, ViewGroup g, int r, int c) { - m.startFragmentTransaction().add(g.getId(),f); - return new FragmentInstantedPage(f); - } - } - - public static class ProgrammablePreferenceFragment extends PreferenceFragment { - private final static String ARG_RES_IX = "res"; - private final static String ARG_PREF_IX = "pref"; - - public static ProgrammablePreferenceFragment newInstance(int res, String pref) { - ProgrammablePreferenceFragment f = new ProgrammablePreferenceFragment(); - Bundle args = new Bundle(); - args.putInt(ARG_RES_IX,res); - args.putString(ARG_PREF_IX,pref); - f.setArguments(args); - return f; - } - - @Override - public void onCreate(Bundle sis) { - super.onCreate(sis); - getPreferenceManager().setSharedPreferencesName(getArguments().getString(ARG_PREF_IX)); - Log.d("PPF", "sp="+getPreferenceManager().getSharedPreferences().toString()); - addPreferencesFromResource(getArguments().getInt(ARG_RES_IX)); - } - } @Override public int getRowCount() { @@ -191,39 +76,23 @@ public class MainGridViewAdapter @Override public boolean isViewFromObject(View view, Object o) { - return ((InstantiatedPage)o).ownsview(view); + return ((Page.InstantiatedPage)o).ownsview(view); } @Override public void destroyItem(ViewGroup viewGroup, int row, int col, Object o) { Log.d("MGVA", "destroy:" + row + "x" + col); - ((InstantiatedPage)o).deinstantiate(this, viewGroup); + ((Page.InstantiatedPage)o).deinstantiate(this, viewGroup); } @Override public void startUpdate(ViewGroup container) { - // Log.d("MGVA", "startUpdate top"); - super.startUpdate(container); - } - - FragmentTransaction startFragmentTransaction() { - if(mFT != null) { return mFT; } - return (mFT = mAct.getFragmentManager().beginTransaction()); + Log.d("MGVA", "startUpdate"); } @Override public void finishUpdate(ViewGroup container) { - if (mAct.getFragmentManager().isDestroyed()) { - mFT = null; - } else if (mFT != null) { - mFT.commitAllowingStateLoss(); - mFT = null; - mAct.getFragmentManager().executePendingTransactions(); - container.postInvalidate(); // TODO: does this help and if so why? - } - - super.finishUpdate(container); - //Log.d("MGVA", "finishUpdate bottom"); + Log.d("MGVA", "finishUpdate"); } @Override @@ -247,6 +116,12 @@ public class MainGridViewAdapter @Override public void onPageScrollStateChanged(int i) { - ; + } + + @Override + public Activity getActivity() { return mAct; } + + @Override + public AudioProvider getAudioProvider() { return mAp; } } diff --git a/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/FragmentPage.java b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/FragmentPage.java new file mode 100644 index 0000000..4e396da --- /dev/null +++ b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/FragmentPage.java @@ -0,0 +1,51 @@ +package com.acmetensortoys.watchviz.vizlib.util; + +import android.app.Fragment; +import android.app.FragmentManager; +import android.view.View; +import android.view.ViewGroup; + +public class FragmentPage extends Page { + public static class FragmentInstantedPage extends InstantiatedPage { + private final Fragment f; + + public FragmentInstantedPage(Fragment f) { + this.f = f; + } + + @Override + public boolean ownsview(View v) { + return v == f.getView(); + } + + @Override + public void deinstantiate(VizLibUI m, ViewGroup g) { + FragmentManager fm = m.getActivity().getFragmentManager(); + fm.beginTransaction().remove(f).commitAllowingStateLoss(); + fm.executePendingTransactions(); + } + } + + private final Fragment f; + + public FragmentPage(Fragment f) { + this.f = f; + } + + public FragmentPage(Fragment f, String t) { + this(f); + this.title = t; + } + + @Override + public InstantiatedPage instantiate(VizLibUI m, ViewGroup g, int r, int c) { + FragmentManager fm = m.getActivity().getFragmentManager(); + fm.beginTransaction().add(g.getId(), f).commitAllowingStateLoss(); + fm.executePendingTransactions(); + return new FragmentInstantedPage(f); + } + + public static FragmentPage makeProgrammablePreferencePage(int x, String pn, String t) { + return new FragmentPage(ProgrammablePreferenceFragment.newInstance(x, pn), t); + } +} diff --git a/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/Page.java b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/Page.java new file mode 100644 index 0000000..a902a88 --- /dev/null +++ b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/Page.java @@ -0,0 +1,42 @@ +package com.acmetensortoys.watchviz.vizlib.util; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; + +import com.acmetensortoys.watchviz.vizlib.AudioProvider; + +public abstract class Page { + public interface VizLibUI { + Activity getActivity(); + AudioProvider getAudioProvider(); + } + + public abstract static class InstantiatedPage { + abstract public boolean ownsview(View v); + abstract public void deinstantiate(VizLibUI m, ViewGroup g); + } + + /* Some Pages just contain View objects directly; go ahead and define those here */ + public static class ViewInstantiatedPage extends InstantiatedPage { + private final View v; + + public ViewInstantiatedPage(View v) { + this.v = v; + } + + @Override + public boolean ownsview(View v2) { + return v == v2; + } + + @Override + public void deinstantiate(Page.VizLibUI m, ViewGroup g) { + g.removeView(v); + } + } + + public String title; + + abstract public InstantiatedPage instantiate(VizLibUI m, ViewGroup g, int r, int c); +} diff --git a/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/ProgrammablePreferenceFragment.java b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/ProgrammablePreferenceFragment.java new file mode 100644 index 0000000..567b6b9 --- /dev/null +++ b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/ProgrammablePreferenceFragment.java @@ -0,0 +1,27 @@ +package com.acmetensortoys.watchviz.vizlib.util; + +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.util.Log; + +public class ProgrammablePreferenceFragment extends PreferenceFragment { + private final static String ARG_RES_IX = "res"; + private final static String ARG_PREF_IX = "pref"; + + public static ProgrammablePreferenceFragment newInstance(int res, String pref) { + ProgrammablePreferenceFragment f = new ProgrammablePreferenceFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_RES_IX, res); + args.putString(ARG_PREF_IX, pref); + f.setArguments(args); + return f; + } + + @Override + public void onCreate(Bundle sis) { + super.onCreate(sis); + getPreferenceManager().setSharedPreferencesName(getArguments().getString(ARG_PREF_IX)); + Log.d("PPF", "sp=" + getPreferenceManager().getSharedPreferences().toString()); + addPreferencesFromResource(getArguments().getInt(ARG_RES_IX)); + } +} diff --git a/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/RendererPage.java b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/RendererPage.java new file mode 100644 index 0000000..2f43dc8 --- /dev/null +++ b/vizlib/src/main/java/com/acmetensortoys/watchviz/vizlib/util/RendererPage.java @@ -0,0 +1,45 @@ +package com.acmetensortoys.watchviz.vizlib.util; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.view.SurfaceView; +import android.view.ViewGroup; + +import com.acmetensortoys.watchviz.vizlib.AudioCanvas; +import com.acmetensortoys.watchviz.vizlib.Rendering; + +public class RendererPage extends Page { + public static final String RENDERER_GLOBAL_SHARED_PREF_NAME = "render_globals"; + + private final Class re; + private final String spn; + + public RendererPage(Class r, String spn) { + this.re = r; + this.spn = spn; + this.title = r.getSimpleName(); + } + + @Override + public InstantiatedPage instantiate(VizLibUI m, ViewGroup g, int r, int c) { + final Activity a = m.getActivity(); + final SurfaceView sv = new SurfaceView(a); + final AudioCanvas ac = new AudioCanvas(r + "x" + c, sv, m.getAudioProvider()); + final Rendering rend; + try { + rend = re.getConstructor(SharedPreferences.class, SharedPreferences.class) + .newInstance( + a.getSharedPreferences(spn, Context.MODE_PRIVATE), + a.getSharedPreferences(RENDERER_GLOBAL_SHARED_PREF_NAME, Context.MODE_PRIVATE)); + ac.setRendering(rend); + } catch (Exception e) { + throw new RuntimeException(e); + } + g.addView(sv, -1, + new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + return new ViewInstantiatedPage(sv); + } +} -- 2.50.1