From 4b187ede4396236ce6b51fbabfac6a42da0be031 Mon Sep 17 00:00:00 2001 From: vanitasvitae Date: Mon, 18 Sep 2017 02:37:17 +0200 Subject: [PATCH] Introduce Fragments --- .../java/de/trac/spherical/FlatFragment.java | 28 +++ .../de/trac/spherical/HandleImageTask.java | 23 --- .../java/de/trac/spherical/MainActivity.java | 183 +++++++++--------- .../de/trac/spherical/ProgressFragment.java | 22 +++ .../de/trac/spherical/SphereFragment.java | 52 +++++ .../spherical/parser/PhotoSphereParser.java | 5 + app/src/main/res/layout/activity_main.xml | 10 +- app/src/main/res/layout/fragment_flat.xml | 11 ++ app/src/main/res/layout/fragment_progress.xml | 12 ++ app/src/main/res/layout/fragment_sphere.xml | 7 + 10 files changed, 239 insertions(+), 114 deletions(-) create mode 100644 app/src/main/java/de/trac/spherical/FlatFragment.java delete mode 100644 app/src/main/java/de/trac/spherical/HandleImageTask.java create mode 100644 app/src/main/java/de/trac/spherical/ProgressFragment.java create mode 100644 app/src/main/java/de/trac/spherical/SphereFragment.java create mode 100644 app/src/main/res/layout/fragment_flat.xml create mode 100644 app/src/main/res/layout/fragment_progress.xml create mode 100644 app/src/main/res/layout/fragment_sphere.xml diff --git a/app/src/main/java/de/trac/spherical/FlatFragment.java b/app/src/main/java/de/trac/spherical/FlatFragment.java new file mode 100644 index 0000000..a924951 --- /dev/null +++ b/app/src/main/java/de/trac/spherical/FlatFragment.java @@ -0,0 +1,28 @@ +package de.trac.spherical; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + +/** + * Created by vanitas on 17.09.17. + */ + +public class FlatFragment extends Fragment { + + private SubsamplingScaleImageView imageView; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_flat, parent, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + imageView = (SubsamplingScaleImageView) view.findViewById(R.id.image_view); + } +} diff --git a/app/src/main/java/de/trac/spherical/HandleImageTask.java b/app/src/main/java/de/trac/spherical/HandleImageTask.java deleted file mode 100644 index 15992ab..0000000 --- a/app/src/main/java/de/trac/spherical/HandleImageTask.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.trac.spherical; - -import android.content.Intent; -import android.os.AsyncTask; - -/** - * Created by vanitas on 15.09.17. - */ - -public class HandleImageTask extends AsyncTask { - - private MainActivity mainActivity; - - public HandleImageTask(MainActivity mainActivity) { - this.mainActivity = mainActivity; - } - - @Override - protected Void doInBackground(Intent... params) { - mainActivity.handleSentImageIntent(params[0]); - return null; - } -} diff --git a/app/src/main/java/de/trac/spherical/MainActivity.java b/app/src/main/java/de/trac/spherical/MainActivity.java index 189081b..ba8f0df 100644 --- a/app/src/main/java/de/trac/spherical/MainActivity.java +++ b/app/src/main/java/de/trac/spherical/MainActivity.java @@ -3,13 +3,17 @@ package de.trac.spherical; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; +import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.ActivityCompat; +import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; +import android.support.v4.view.GestureDetectorCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; @@ -21,38 +25,75 @@ import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; -import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.Toast; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; import de.trac.spherical.parser.PhotoSphereMetadata; import de.trac.spherical.parser.PhotoSphereParser; import de.trac.spherical.rendering.PhotoSphereSurfaceView; + public class MainActivity extends AppCompatActivity { public static final String TAG = "Spherical"; - public static final String MIME_PHOTO_SPHERE = "application/vnd.google.panorama360+jpg"; - public static final String MIME_IMAGE = "image/*"; - private static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 387; - private PhotoSphereSurfaceView surfaceView; + private FragmentManager fm; + + //UI private FloatingActionButton fab; private Toolbar toolbar; + private GestureDetectorCompat gestureDetector; + private ProgressFragment progressFragment; + private FlatFragment flatFragment; + private SphereFragment sphereFragment; + + //Cache private Intent cachedIntent; + private Bitmap bitmap; + private PhotoSphereMetadata metadata; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + setupUI(); + fm = getSupportFragmentManager(); + + handleIntent(getIntent()); + } + + private ProgressFragment showProgressFragment() { + if (progressFragment == null) { + progressFragment = new ProgressFragment(); + } + fm.beginTransaction().replace(R.id.container_fragment, progressFragment, "prog").commit(); + return progressFragment; + } + + private FlatFragment showFlatImageFragment() { + if (flatFragment == null) { + flatFragment = new FlatFragment(); + } + fm.beginTransaction().replace(R.id.container_fragment, flatFragment, "flat").commit(); + return flatFragment; + } + + private SphereFragment showSphereFragment() { + if (sphereFragment == null) { + sphereFragment = new SphereFragment(); + } + fm.beginTransaction().replace(R.id.container_fragment, sphereFragment, "sphere").commit(); + return sphereFragment; + } + + private void setupUI() { // Prepare UI toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); @@ -73,14 +114,8 @@ public class MainActivity extends AppCompatActivity { Window w = getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); } - - // Initialize renderer and setup surface view. - LinearLayout container = (LinearLayout) findViewById(R.id.container); - surfaceView = new PhotoSphereSurfaceView(this); - container.addView(surfaceView); - // Detect gestures like single taps. - final GestureDetector gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() { + gestureDetector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapConfirmed(MotionEvent event) { displayUI(!fab.isShown()); @@ -88,15 +123,6 @@ public class MainActivity extends AppCompatActivity { } }); - - surfaceView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - return gestureDetector.onTouchEvent(event); - } - }); - - handleIntent(getIntent()); } private void handleIntent(Intent intent) { @@ -116,25 +142,26 @@ public class MainActivity extends AppCompatActivity { private void checkPermissionAndHandleSentImage(Intent intent) { int status = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); if (status == PackageManager.PERMISSION_GRANTED) { - new HandleImageTask(this).doInBackground(intent); + showProgressFragment(); + new HandleSentImageTask().doInBackground(intent); + return; } // Cache intent and request permission this.cachedIntent = intent; ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_READ_EXTERNAL_STORAGE); - } @Override - public void onRequestPermissionsResult(int requestCode, - String permissions[], int[] grantResults) { + public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_READ_EXTERNAL_STORAGE: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - new HandleImageTask(this).doInBackground(cachedIntent); + showProgressFragment(); + new HandleSentImageTask().doInBackground(cachedIntent); } else { Toast.makeText(this, R.string.toast_missing_permission, Toast.LENGTH_LONG).show(); } @@ -177,8 +204,8 @@ public class MainActivity extends AppCompatActivity { } /** - * Distinguish type of sent image. Images with the MIME type of a photosphere will be directly - * displayed, while images with MIME type image/* are being manually tested using {@link PhotoSphereParser}. + * Distinguish type of sent bitmap. Images with the MIME type of a photosphere will be directly + * displayed, while images with MIME type bitmap/* are being manually tested using {@link PhotoSphereParser}. * @param intent incoming intent. */ void handleSentImageIntent(Intent intent) { @@ -191,13 +218,28 @@ public class MainActivity extends AppCompatActivity { return; } + Log.d(TAG, "START LOADING BITMAP"); + try { + bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri)); + metadata = PhotoSphereParser.parse(getContentResolver().openInputStream(imageUri)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + Log.d(TAG, "FINISHED LOADING BITMAP"); + switch (type) { case MIME_PHOTO_SPHERE: - displayPhotoSphere(imageUri); + displayPhotoSphere(); break; default: - displayMaybePhotoSphere(imageUri); + if (metadata != null) { + displayPhotoSphere(); + } else { + displayFlatImage(); + } break; } @@ -206,72 +248,23 @@ public class MainActivity extends AppCompatActivity { } } - /** - * Check, whether the sent photo is a photo sphere and display either a sphere, or a plain image. - * @param uri - */ - private void displayMaybePhotoSphere(Uri uri) { - try { - InputStream inputStream = getContentResolver().openInputStream(uri); - String xml = PhotoSphereParser.getXMLContent(inputStream); - PhotoSphereMetadata metadata = PhotoSphereParser.parse(xml); - - if (metadata == null || !metadata.isUsePanoramaViewer()) { - displayFlatImage(getContentResolver().openInputStream(uri)); - } else { - displayPhotoSphere(getContentResolver().openInputStream(uri), metadata); - } - - } catch (FileNotFoundException e) { - Log.e(TAG, "File not found.", e); - Toast.makeText(this, R.string.toast_file_not_found, Toast.LENGTH_SHORT).show(); - } catch (IOException e) { - Log.e(TAG, "IOException: ", e); - Toast.makeText(this, R.string.toast_io_error, Toast.LENGTH_SHORT).show(); - } - } - /** * Display a photo sphere. - * @param uri */ - private void displayPhotoSphere(Uri uri) { - try { - InputStream inputStream = getContentResolver().openInputStream(uri); - String xml = PhotoSphereParser.getXMLContent(inputStream); - PhotoSphereMetadata metadata = PhotoSphereParser.parse(xml); - - if (metadata == null) { - Log.e(TAG, "Metadata is null. Fall back to flat image."); - displayFlatImage(getContentResolver().openInputStream(uri)); - } - - displayPhotoSphere(getContentResolver().openInputStream(uri), metadata); - - } catch (FileNotFoundException e) { - Log.e(TAG, "File not found.", e); - Toast.makeText(this, R.string.toast_file_not_found, Toast.LENGTH_SHORT).show(); - } catch (IOException e) { - Log.e(TAG, "IOException: ", e); - Toast.makeText(this, R.string.toast_io_error, Toast.LENGTH_SHORT).show(); - } - } - - private void displayPhotoSphere(InputStream inputStream, PhotoSphereMetadata metadata) { - surfaceView.setBitmap(BitmapFactory.decodeStream(inputStream)); - Log.d(TAG, "Display Photo PhotoSphere!"); + private void displayPhotoSphere() { + SphereFragment spf = showSphereFragment(); + spf.displayPhotoSphere(bitmap); } /** - * Display a flat image. - * @param inputStream + * Display a flat bitmap. */ - private void displayFlatImage(InputStream inputStream) { + private void displayFlatImage() { Log.d(TAG, "Display Flat Image!"); - displayPhotoSphere(inputStream, new PhotoSphereMetadata()); + //displayPhotoSphere(inputStream, new PhotoSphereMetadata()); } - public int getStatusBarHeight() { + private int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { @@ -280,4 +273,20 @@ public class MainActivity extends AppCompatActivity { return result; } + public GestureDetectorCompat getGestureDetector() { + return gestureDetector; + } + + public Bitmap getBitmap() { + return bitmap; + } + + private class HandleSentImageTask extends AsyncTask { + + @Override + protected Void doInBackground(Intent... params) { + handleSentImageIntent(params[0]); + return null; + } + } } diff --git a/app/src/main/java/de/trac/spherical/ProgressFragment.java b/app/src/main/java/de/trac/spherical/ProgressFragment.java new file mode 100644 index 0000000..ef3d371 --- /dev/null +++ b/app/src/main/java/de/trac/spherical/ProgressFragment.java @@ -0,0 +1,22 @@ +package de.trac.spherical; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * Created by vanitas on 18.09.17. + */ +public class ProgressFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_progress, parent, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + } +} diff --git a/app/src/main/java/de/trac/spherical/SphereFragment.java b/app/src/main/java/de/trac/spherical/SphereFragment.java new file mode 100644 index 0000000..494b89e --- /dev/null +++ b/app/src/main/java/de/trac/spherical/SphereFragment.java @@ -0,0 +1,52 @@ +package de.trac.spherical; + +import android.graphics.Bitmap; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; + +import de.trac.spherical.rendering.PhotoSphereSurfaceView; + +/** + * Created by vanitas on 17.09.17. + */ +public class SphereFragment extends Fragment implements View.OnTouchListener { + + private PhotoSphereSurfaceView surfaceView; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_sphere, parent, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + FrameLayout fragmentRoot = (FrameLayout) view.findViewById(R.id.container_sphere); + surfaceView = new PhotoSphereSurfaceView(getContext()); + + // Initialize renderer and setup surface view. + fragmentRoot.addView(surfaceView); + + surfaceView.setOnTouchListener(this); + surfaceView.setBitmap(getMainActivity().getBitmap()); + } + + public void displayPhotoSphere(Bitmap bitmap) { + //surfaceView.setBitmap(bitmap); + Log.d(MainActivity.TAG, "Display Photo Sphere!"); + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + return getMainActivity().getGestureDetector().onTouchEvent(event); + } + + private MainActivity getMainActivity() { + return (MainActivity) getActivity(); + } +} diff --git a/app/src/main/java/de/trac/spherical/parser/PhotoSphereParser.java b/app/src/main/java/de/trac/spherical/parser/PhotoSphereParser.java index 4e0fa78..d73f065 100644 --- a/app/src/main/java/de/trac/spherical/parser/PhotoSphereParser.java +++ b/app/src/main/java/de/trac/spherical/parser/PhotoSphereParser.java @@ -150,6 +150,11 @@ public class PhotoSphereParser { return meta; } + public static PhotoSphereMetadata parse(InputStream inputStream) throws IOException { + String xml = getXMLContent(inputStream); + return parse(xml); + } + private static void throwIfUnexpectedEOF(int actual, int expected) throws EOFException { if (actual != expected) { throw new EOFException("Unexpected EOF!"); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index ea61a5c..39eac7d 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -22,14 +22,16 @@ app:theme="@style/AppTheme.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat" /> - - + diff --git a/app/src/main/res/layout/fragment_flat.xml b/app/src/main/res/layout/fragment_flat.xml new file mode 100644 index 0000000..3de3db4 --- /dev/null +++ b/app/src/main/res/layout/fragment_flat.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_progress.xml b/app/src/main/res/layout/fragment_progress.xml new file mode 100644 index 0000000..9cdb77a --- /dev/null +++ b/app/src/main/res/layout/fragment_progress.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_sphere.xml b/app/src/main/res/layout/fragment_sphere.xml new file mode 100644 index 0000000..ed77d1f --- /dev/null +++ b/app/src/main/res/layout/fragment_sphere.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file