Fix losing communication service on screen rotation.
Change-Id: I8ae72857ce65783fe79cd3b911b83b4c70deece6
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res/org.libreoffice.impressremote"
|
||||
android:id="@+id/presentation_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -15,9 +16,10 @@
|
||||
android:id="@+id/presentation_coverflow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="5dip"
|
||||
coverflow:imageHeight="150dip"
|
||||
coverflow:imageWidth="180dip"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
coverflow:imageHeight="200dip"
|
||||
coverflow:imageWidth="240dip"
|
||||
coverflow:withReflection="false" />
|
||||
|
||||
<TextView
|
||||
@@ -36,6 +38,8 @@
|
||||
android:layout_marginRight="6dp"
|
||||
android:contentDescription="@string/presentation_ui_resizehandle"
|
||||
android:paddingBottom="5dp"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/handle" />
|
||||
|
@@ -112,8 +112,6 @@ public class PresentationActivity extends SherlockFragmentActivity {
|
||||
mCommunicationService = ((CommunicationService.CBinder) aService)
|
||||
.getService();
|
||||
|
||||
mPresentationFragment
|
||||
.setCommunicationService(mCommunicationService);
|
||||
mThumbnailFragment.setCommunicationService(mCommunicationService);
|
||||
|
||||
}
|
||||
|
@@ -6,9 +6,11 @@ import org.libreoffice.impressremote.communication.SlideShow;
|
||||
import pl.polidea.coverflow.AbstractCoverFlowImageAdapter;
|
||||
import pl.polidea.coverflow.CoverFlow;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
@@ -16,6 +18,7 @@ import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
@@ -39,7 +42,6 @@ public class PresentationFragment extends SherlockFragment {
|
||||
private TextView mNumberText;
|
||||
|
||||
private CommunicationService mCommunicationService;
|
||||
private SlideShow mSlideShow;
|
||||
|
||||
private float mOriginalCoverflowWidth;
|
||||
private float mOriginalCoverflowHeight;
|
||||
@@ -47,8 +49,37 @@ public class PresentationFragment extends SherlockFragment {
|
||||
private float mNewCoverflowWidth = 0;
|
||||
private float mNewCoverflowHeight = 0;
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName aClassName,
|
||||
IBinder aService) {
|
||||
mCommunicationService = ((CommunicationService.CBinder) aService)
|
||||
.getService();
|
||||
|
||||
if (mTopView != null) {
|
||||
mTopView.setAdapter(new ThumbnailAdapter(mContext,
|
||||
mCommunicationService.getSlideShow()));
|
||||
mTopView.setSelection(mCommunicationService.getSlideShow()
|
||||
.getCurrentSlide(), true);
|
||||
mTopView.setOnItemSelectedListener(new ClickListener());
|
||||
}
|
||||
|
||||
updateSlideNumberDisplay();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName aClassName) {
|
||||
mCommunicationService = null;
|
||||
}
|
||||
};
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
getActivity().bindService(
|
||||
new Intent(getActivity().getApplicationContext(),
|
||||
CommunicationService.class),
|
||||
mConnection, Context.BIND_IMPORTANT);
|
||||
mContext = getActivity().getApplicationContext();
|
||||
container.removeAllViews();
|
||||
View v = inflater.inflate(R.layout.fragment_presentation, container,
|
||||
@@ -69,9 +100,6 @@ public class PresentationFragment extends SherlockFragment {
|
||||
mHandle = (ImageView) v.findViewById(R.id.presentation_handle);
|
||||
mHandle.setOnTouchListener(new SizeListener());
|
||||
|
||||
// Call again to set things up if necessary.
|
||||
setCommunicationService(mCommunicationService);
|
||||
|
||||
// Save the height/width for future reference
|
||||
mOriginalCoverflowHeight = mTopView.getImageHeight();
|
||||
mOriginalCoverflowWidth = mTopView.getImageWidth();
|
||||
@@ -95,11 +123,13 @@ public class PresentationFragment extends SherlockFragment {
|
||||
LocalBroadcastManager
|
||||
.getInstance(getActivity().getApplicationContext())
|
||||
.registerReceiver(mListener, aFilter);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
getActivity().unbindService(mConnection);
|
||||
super.onDestroyView();
|
||||
LocalBroadcastManager
|
||||
.getInstance(getActivity().getApplicationContext())
|
||||
@@ -108,9 +138,11 @@ public class PresentationFragment extends SherlockFragment {
|
||||
}
|
||||
|
||||
private void updateSlideNumberDisplay() {
|
||||
int aSlide = mSlideShow.getCurrentSlide();
|
||||
mNumberText.setText((aSlide + 1) + "/" + mSlideShow.getSize());
|
||||
mNotes.loadData(mSlideShow.getNotes(aSlide), "text/html", null);
|
||||
int aSlide = mCommunicationService.getSlideShow().getCurrentSlide();
|
||||
mNumberText.setText((aSlide + 1) + "/"
|
||||
+ mCommunicationService.getSlideShow().getSize());
|
||||
mNotes.loadData(mCommunicationService.getSlideShow().getNotes(aSlide),
|
||||
"text/html", null);
|
||||
}
|
||||
|
||||
// -------------------------------------------------- RESIZING LISTENER ----
|
||||
@@ -207,22 +239,6 @@ public class PresentationFragment extends SherlockFragment {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------- MESSAGE HANDLER ----
|
||||
public void setCommunicationService(
|
||||
CommunicationService aCommunicationService) {
|
||||
mCommunicationService = aCommunicationService;
|
||||
if (mCommunicationService == null)
|
||||
return;
|
||||
|
||||
mSlideShow = mCommunicationService.getSlideShow();
|
||||
if (mTopView != null && mSlideShow != null) {
|
||||
mTopView.setAdapter(new ThumbnailAdapter(mContext, mSlideShow));
|
||||
mTopView.setSelection(mSlideShow.getCurrentSlide(), true);
|
||||
mTopView.setOnItemSelectedListener(new ClickListener());
|
||||
}
|
||||
|
||||
updateSlideNumberDisplay();
|
||||
}
|
||||
|
||||
private BroadcastReceiver mListener = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
|
@@ -1,197 +0,0 @@
|
||||
///* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
///*
|
||||
// * This file is part of the LibreOffice project.
|
||||
// *
|
||||
// * This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// * file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
// */
|
||||
//package org.libreoffice.impressremote.communication;
|
||||
//
|
||||
//import org.libreoffice.impressremote.PresentationActivity;
|
||||
//import org.libreoffice.impressremote.R;
|
||||
//import org.libreoffice.impressremote.communication.Server.Protocol;
|
||||
//
|
||||
//import android.app.Activity;
|
||||
//import android.content.ComponentName;
|
||||
//import android.content.Context;
|
||||
//import android.content.Intent;
|
||||
//import android.content.ServiceConnection;
|
||||
//import android.graphics.Bitmap;
|
||||
//import android.os.Bundle;
|
||||
//import android.os.Handler;
|
||||
//import android.os.IBinder;
|
||||
//import android.os.Message;
|
||||
//import android.os.Messenger;
|
||||
//import android.view.View;
|
||||
//import android.view.View.OnClickListener;
|
||||
//import android.widget.Button;
|
||||
//import android.widget.ImageView;
|
||||
//import android.widget.TextView;
|
||||
//
|
||||
//public class TestClient extends Activity {
|
||||
//
|
||||
// private boolean mCurrentPreviewImageMissing = false;
|
||||
//
|
||||
// private boolean mIsBound = false;
|
||||
//
|
||||
// private CommunicationService mCommunicationService;
|
||||
//
|
||||
// final Messenger mMessenger = new Messenger(new MessageHandler());
|
||||
//
|
||||
// /** Called when the activity is first created. */
|
||||
// @Override
|
||||
// public void onCreate(Bundle savedInstanceState) {
|
||||
// super.onCreate(savedInstanceState);
|
||||
// setContentView(R.layout.testlayout);
|
||||
// setupUI();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onResume() {
|
||||
// super.onResume();
|
||||
// doBindService();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // FIXME: move all necessary code to CommunicationService.onUnbind
|
||||
//
|
||||
// @Override
|
||||
// protected void onPause() {
|
||||
// super.onPause();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onBackPressed() {
|
||||
// // TODO Auto-generated method stub
|
||||
// mCommunicationService.disconnect();
|
||||
// stopService(new Intent(this, CommunicationService.class));
|
||||
// doUnbindService();
|
||||
// finish();
|
||||
// super.onBackPressed();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onStop() {
|
||||
// // TODO Auto-generated method stub
|
||||
// super.onStop();
|
||||
// // mCommunicationService.disconnect();
|
||||
// // stopService(new Intent(this, CommunicationService.class));
|
||||
// }
|
||||
//
|
||||
// private ServiceConnection mConnection = new ServiceConnection() {
|
||||
// @Override
|
||||
// public void onServiceConnected(ComponentName aClassName,
|
||||
// IBinder aService) {
|
||||
// mCommunicationService = ((CommunicationService.CBinder) aService)
|
||||
// .getService();
|
||||
// mCommunicationService.connectTo(new Server(Protocol.NETWORK,
|
||||
// "10.0.2.2", "TestServer", 0l));
|
||||
// mCommunicationService.setActivityMessenger(mMessenger);
|
||||
// enableButtons(true);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onServiceDisconnected(ComponentName aClassName) {
|
||||
// mCommunicationService = null;
|
||||
// enableButtons(false);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// void doBindService() {
|
||||
// Intent aIntent = new Intent(this, CommunicationService.class);
|
||||
// startService(aIntent);
|
||||
// bindService(aIntent, mConnection, Context.BIND_IMPORTANT);
|
||||
// mIsBound = true;
|
||||
// }
|
||||
//
|
||||
// void doUnbindService() {
|
||||
// mCommunicationService.setActivityMessenger(null);
|
||||
// if (mIsBound) {
|
||||
// unbindService(mConnection);
|
||||
// mIsBound = false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private Button mButtonNext;
|
||||
//
|
||||
// private Button mButtonPrevious;
|
||||
//
|
||||
// private ImageView mImageView;
|
||||
//
|
||||
// private TextView mSlideLabel;
|
||||
//
|
||||
// private void setupUI() {
|
||||
// mButtonNext = (Button) findViewById(R.id.button_next);
|
||||
// mButtonPrevious = (Button) findViewById(R.id.button_previous);
|
||||
// mImageView = (ImageView) findViewById(R.id.image_preview);
|
||||
// mSlideLabel = (TextView) findViewById(R.id.label_curSlide);
|
||||
//
|
||||
// enableButtons(false);
|
||||
//
|
||||
// mButtonNext.setOnClickListener(new OnClickListener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// mCommunicationService.getTransmitter().nextTransition();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
// mButtonPrevious.setOnClickListener(new OnClickListener() {
|
||||
//
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// mCommunicationService.getTransmitter().previousTransition();
|
||||
//
|
||||
// }
|
||||
//
|
||||
// });
|
||||
//
|
||||
// Button mThumbnailButton = (Button) findViewById(R.id.button_thumbnail);
|
||||
//
|
||||
// mThumbnailButton.setOnClickListener(new OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// Intent aIntent = new Intent(TestClient.this,
|
||||
// PresentationActivity.class);
|
||||
// startActivity(aIntent);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void enableButtons(boolean aEnabled) {
|
||||
// mButtonNext.setEnabled(aEnabled);
|
||||
// mButtonPrevious.setEnabled(aEnabled);
|
||||
// }
|
||||
//
|
||||
// class MessageHandler extends Handler {
|
||||
// @Override
|
||||
// public void handleMessage(Message aMessage) {
|
||||
// Bundle aData = aMessage.getData();
|
||||
// switch (aMessage.what) {
|
||||
// case CommunicationService.MSG_SLIDE_CHANGED:
|
||||
// int newSlide = aData.getInt("slide_number");
|
||||
// mSlideLabel.setText("Slide " + newSlide);
|
||||
// mCurrentPreviewImageMissing = true;
|
||||
// // We continue on to try and update the image.
|
||||
// case CommunicationService.MSG_SLIDE_PREVIEW:
|
||||
// int aSlideNumber = aData.getInt("slide_number");
|
||||
// if (mCurrentPreviewImageMissing) {
|
||||
// Bitmap aImage = mCommunicationService.getSlideShow()
|
||||
// .getImage(aSlideNumber);
|
||||
// if (aImage != null) {
|
||||
// mImageView.setImageBitmap(aImage);
|
||||
// mCurrentPreviewImageMissing = false;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
///* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@@ -39,350 +39,350 @@ import android.widget.SpinnerAdapter;
|
||||
*/
|
||||
public class CoverFlow extends Gallery {
|
||||
|
||||
/**
|
||||
* Graphics Camera used for transforming the matrix of ImageViews.
|
||||
*/
|
||||
private final Camera mCamera = new Camera();
|
||||
/**
|
||||
* Graphics Camera used for transforming the matrix of ImageViews.
|
||||
*/
|
||||
private final Camera mCamera = new Camera();
|
||||
|
||||
/**
|
||||
* The maximum angle the Child ImageView will be rotated by.
|
||||
*/
|
||||
private int mMaxRotationAngle = 60;
|
||||
/**
|
||||
* The maximum angle the Child ImageView will be rotated by.
|
||||
*/
|
||||
private int mMaxRotationAngle = 30;
|
||||
|
||||
/**
|
||||
* The maximum zoom on the centre Child.
|
||||
*/
|
||||
private int mMaxZoom = -160;
|
||||
/**
|
||||
* The maximum zoom on the centre Child.
|
||||
*/
|
||||
private int mMaxZoom = -100;
|
||||
|
||||
/**
|
||||
* The Centre of the Coverflow.
|
||||
*/
|
||||
private int mCoveflowCenter;
|
||||
/**
|
||||
* The Centre of the Coverflow.
|
||||
*/
|
||||
private int mCoveflowCenter;
|
||||
|
||||
/** The image height. */
|
||||
private float imageHeight;
|
||||
/** The image height. */
|
||||
private float imageHeight;
|
||||
|
||||
/** The image width. */
|
||||
private float imageWidth;
|
||||
/** The image width. */
|
||||
private float imageWidth;
|
||||
|
||||
/** The reflection gap. */
|
||||
private float reflectionGap;
|
||||
/** The reflection gap. */
|
||||
private float reflectionGap;
|
||||
|
||||
/** The with reflection. */
|
||||
private boolean withReflection;
|
||||
/** The with reflection. */
|
||||
private boolean withReflection;
|
||||
|
||||
/** The image reflection ratio. */
|
||||
private float imageReflectionRatio;
|
||||
/** The image reflection ratio. */
|
||||
private float imageReflectionRatio;
|
||||
|
||||
/**
|
||||
* Gets the image height.
|
||||
*
|
||||
* @return the image height
|
||||
*/
|
||||
public float getImageHeight() {
|
||||
return imageHeight;
|
||||
}
|
||||
/**
|
||||
* Gets the image height.
|
||||
*
|
||||
* @return the image height
|
||||
*/
|
||||
public float getImageHeight() {
|
||||
return imageHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image height.
|
||||
*
|
||||
* @param imageHeight
|
||||
* the new image height
|
||||
*/
|
||||
public void setImageHeight(final float imageHeight) {
|
||||
this.imageHeight = imageHeight;
|
||||
}
|
||||
/**
|
||||
* Sets the image height.
|
||||
*
|
||||
* @param imageHeight
|
||||
* the new image height
|
||||
*/
|
||||
public void setImageHeight(final float imageHeight) {
|
||||
this.imageHeight = imageHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image width.
|
||||
*
|
||||
* @return the image width
|
||||
*/
|
||||
public float getImageWidth() {
|
||||
return imageWidth;
|
||||
}
|
||||
/**
|
||||
* Gets the image width.
|
||||
*
|
||||
* @return the image width
|
||||
*/
|
||||
public float getImageWidth() {
|
||||
return imageWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image width.
|
||||
*
|
||||
* @param imageWidth
|
||||
* the new image width
|
||||
*/
|
||||
public void setImageWidth(final float imageWidth) {
|
||||
this.imageWidth = imageWidth;
|
||||
}
|
||||
/**
|
||||
* Sets the image width.
|
||||
*
|
||||
* @param imageWidth
|
||||
* the new image width
|
||||
*/
|
||||
public void setImageWidth(final float imageWidth) {
|
||||
this.imageWidth = imageWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the reflection gap.
|
||||
*
|
||||
* @return the reflection gap
|
||||
*/
|
||||
public float getReflectionGap() {
|
||||
return reflectionGap;
|
||||
}
|
||||
/**
|
||||
* Gets the reflection gap.
|
||||
*
|
||||
* @return the reflection gap
|
||||
*/
|
||||
public float getReflectionGap() {
|
||||
return reflectionGap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the reflection gap.
|
||||
*
|
||||
* @param reflectionGap
|
||||
* the new reflection gap
|
||||
*/
|
||||
public void setReflectionGap(final float reflectionGap) {
|
||||
this.reflectionGap = reflectionGap;
|
||||
}
|
||||
/**
|
||||
* Sets the reflection gap.
|
||||
*
|
||||
* @param reflectionGap
|
||||
* the new reflection gap
|
||||
*/
|
||||
public void setReflectionGap(final float reflectionGap) {
|
||||
this.reflectionGap = reflectionGap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is with reflection.
|
||||
*
|
||||
* @return true, if is with reflection
|
||||
*/
|
||||
public boolean isWithReflection() {
|
||||
return withReflection;
|
||||
}
|
||||
/**
|
||||
* Checks if is with reflection.
|
||||
*
|
||||
* @return true, if is with reflection
|
||||
*/
|
||||
public boolean isWithReflection() {
|
||||
return withReflection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the with reflection.
|
||||
*
|
||||
* @param withReflection
|
||||
* the new with reflection
|
||||
*/
|
||||
public void setWithReflection(final boolean withReflection) {
|
||||
this.withReflection = withReflection;
|
||||
}
|
||||
/**
|
||||
* Sets the with reflection.
|
||||
*
|
||||
* @param withReflection
|
||||
* the new with reflection
|
||||
*/
|
||||
public void setWithReflection(final boolean withReflection) {
|
||||
this.withReflection = withReflection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the image reflection ratio.
|
||||
*
|
||||
* @param imageReflectionRatio
|
||||
* the new image reflection ratio
|
||||
*/
|
||||
public void setImageReflectionRatio(final float imageReflectionRatio) {
|
||||
this.imageReflectionRatio = imageReflectionRatio;
|
||||
}
|
||||
/**
|
||||
* Sets the image reflection ratio.
|
||||
*
|
||||
* @param imageReflectionRatio
|
||||
* the new image reflection ratio
|
||||
*/
|
||||
public void setImageReflectionRatio(final float imageReflectionRatio) {
|
||||
this.imageReflectionRatio = imageReflectionRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image reflection ratio.
|
||||
*
|
||||
* @return the image reflection ratio
|
||||
*/
|
||||
public float getImageReflectionRatio() {
|
||||
return imageReflectionRatio;
|
||||
}
|
||||
/**
|
||||
* Gets the image reflection ratio.
|
||||
*
|
||||
* @return the image reflection ratio
|
||||
*/
|
||||
public float getImageReflectionRatio() {
|
||||
return imageReflectionRatio;
|
||||
}
|
||||
|
||||
public CoverFlow(final Context context) {
|
||||
super(context);
|
||||
this.setStaticTransformationsEnabled(true);
|
||||
}
|
||||
public CoverFlow(final Context context) {
|
||||
super(context);
|
||||
this.setStaticTransformationsEnabled(true);
|
||||
}
|
||||
|
||||
public CoverFlow(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.galleryStyle);
|
||||
}
|
||||
public CoverFlow(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.galleryStyle);
|
||||
}
|
||||
|
||||
public CoverFlow(final Context context, final AttributeSet attrs,
|
||||
final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
parseAttributes(context, attrs);
|
||||
this.setStaticTransformationsEnabled(true);
|
||||
}
|
||||
public CoverFlow(final Context context, final AttributeSet attrs,
|
||||
final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
parseAttributes(context, attrs);
|
||||
this.setStaticTransformationsEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max rotational angle of the image.
|
||||
*
|
||||
* @return the mMaxRotationAngle
|
||||
*/
|
||||
public int getMaxRotationAngle() {
|
||||
return mMaxRotationAngle;
|
||||
}
|
||||
/**
|
||||
* Get the max rotational angle of the image.
|
||||
*
|
||||
* @return the mMaxRotationAngle
|
||||
*/
|
||||
public int getMaxRotationAngle() {
|
||||
return mMaxRotationAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the.
|
||||
*
|
||||
* @param adapter
|
||||
* the new adapter
|
||||
*/
|
||||
@Override
|
||||
public void setAdapter(final SpinnerAdapter adapter) {
|
||||
if (!(adapter instanceof AbstractCoverFlowImageAdapter)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The adapter should derive from "
|
||||
+ AbstractCoverFlowImageAdapter.class
|
||||
.getName());
|
||||
}
|
||||
final AbstractCoverFlowImageAdapter coverAdapter = (AbstractCoverFlowImageAdapter) adapter;
|
||||
coverAdapter.setWidth(imageWidth);
|
||||
coverAdapter.setHeight(imageHeight);
|
||||
if (withReflection) {
|
||||
final ReflectingImageAdapter reflectAdapter = new ReflectingImageAdapter(
|
||||
coverAdapter);
|
||||
reflectAdapter.setReflectionGap(reflectionGap);
|
||||
reflectAdapter.setWidthRatio(imageReflectionRatio);
|
||||
reflectAdapter.setWidth(imageWidth);
|
||||
reflectAdapter.setHeight(imageHeight * (1 + imageReflectionRatio));
|
||||
super.setAdapter(reflectAdapter);
|
||||
} else {
|
||||
super.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets the.
|
||||
*
|
||||
* @param adapter
|
||||
* the new adapter
|
||||
*/
|
||||
@Override
|
||||
public void setAdapter(final SpinnerAdapter adapter) {
|
||||
if (!(adapter instanceof AbstractCoverFlowImageAdapter)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The adapter should derive from "
|
||||
+ AbstractCoverFlowImageAdapter.class
|
||||
.getName());
|
||||
}
|
||||
final AbstractCoverFlowImageAdapter coverAdapter = (AbstractCoverFlowImageAdapter) adapter;
|
||||
coverAdapter.setWidth(imageWidth);
|
||||
coverAdapter.setHeight(imageHeight);
|
||||
if (withReflection) {
|
||||
final ReflectingImageAdapter reflectAdapter = new ReflectingImageAdapter(
|
||||
coverAdapter);
|
||||
reflectAdapter.setReflectionGap(reflectionGap);
|
||||
reflectAdapter.setWidthRatio(imageReflectionRatio);
|
||||
reflectAdapter.setWidth(imageWidth);
|
||||
reflectAdapter.setHeight(imageHeight * (1 + imageReflectionRatio));
|
||||
super.setAdapter(reflectAdapter);
|
||||
} else {
|
||||
super.setAdapter(adapter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max rotational angle of each image.
|
||||
*
|
||||
* @param maxRotationAngle
|
||||
* the mMaxRotationAngle to set
|
||||
*/
|
||||
public void setMaxRotationAngle(final int maxRotationAngle) {
|
||||
mMaxRotationAngle = maxRotationAngle;
|
||||
}
|
||||
/**
|
||||
* Set the max rotational angle of each image.
|
||||
*
|
||||
* @param maxRotationAngle
|
||||
* the mMaxRotationAngle to set
|
||||
*/
|
||||
public void setMaxRotationAngle(final int maxRotationAngle) {
|
||||
mMaxRotationAngle = maxRotationAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Max zoom of the centre image.
|
||||
*
|
||||
* @return the mMaxZoom
|
||||
*/
|
||||
public int getMaxZoom() {
|
||||
return mMaxZoom;
|
||||
}
|
||||
/**
|
||||
* Get the Max zoom of the centre image.
|
||||
*
|
||||
* @return the mMaxZoom
|
||||
*/
|
||||
public int getMaxZoom() {
|
||||
return mMaxZoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max zoom of the centre image.
|
||||
*
|
||||
* @param maxZoom
|
||||
* the mMaxZoom to set
|
||||
*/
|
||||
public void setMaxZoom(final int maxZoom) {
|
||||
mMaxZoom = maxZoom;
|
||||
}
|
||||
/**
|
||||
* Set the max zoom of the centre image.
|
||||
*
|
||||
* @param maxZoom
|
||||
* the mMaxZoom to set
|
||||
*/
|
||||
public void setMaxZoom(final int maxZoom) {
|
||||
mMaxZoom = maxZoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Centre of the Coverflow.
|
||||
*
|
||||
* @return The centre of this Coverflow.
|
||||
*/
|
||||
private int getCenterOfCoverflow() {
|
||||
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
|
||||
+ getPaddingLeft();
|
||||
}
|
||||
/**
|
||||
* Get the Centre of the Coverflow.
|
||||
*
|
||||
* @return The centre of this Coverflow.
|
||||
*/
|
||||
private int getCenterOfCoverflow() {
|
||||
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
|
||||
+ getPaddingLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Centre of the View.
|
||||
*
|
||||
* @return The centre of the given view.
|
||||
*/
|
||||
private static int getCenterOfView(final View view) {
|
||||
return view.getLeft() + view.getWidth() / 2;
|
||||
}
|
||||
/**
|
||||
* Get the Centre of the View.
|
||||
*
|
||||
* @return The centre of the given view.
|
||||
*/
|
||||
private static int getCenterOfView(final View view) {
|
||||
return view.getLeft() + view.getWidth() / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see #setStaticTransformationsEnabled(boolean)
|
||||
*/
|
||||
@Override
|
||||
protected boolean getChildStaticTransformation(final View child,
|
||||
final Transformation t) {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see #setStaticTransformationsEnabled(boolean)
|
||||
*/
|
||||
@Override
|
||||
protected boolean getChildStaticTransformation(final View child,
|
||||
final Transformation t) {
|
||||
|
||||
final int childCenter = getCenterOfView(child);
|
||||
final int childWidth = child.getWidth();
|
||||
int rotationAngle = 0;
|
||||
final int childCenter = getCenterOfView(child);
|
||||
final int childWidth = child.getWidth();
|
||||
int rotationAngle = 0;
|
||||
|
||||
t.clear();
|
||||
t.setTransformationType(Transformation.TYPE_MATRIX);
|
||||
t.clear();
|
||||
t.setTransformationType(Transformation.TYPE_MATRIX);
|
||||
|
||||
if (childCenter == mCoveflowCenter) {
|
||||
transformImageBitmap((ImageView) child, t, 0);
|
||||
} else {
|
||||
rotationAngle = (int) ((float) (mCoveflowCenter - childCenter)
|
||||
/ childWidth * mMaxRotationAngle);
|
||||
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
|
||||
rotationAngle = rotationAngle < 0 ? -mMaxRotationAngle
|
||||
: mMaxRotationAngle;
|
||||
}
|
||||
transformImageBitmap((ImageView) child, t, rotationAngle);
|
||||
}
|
||||
if (childCenter == mCoveflowCenter) {
|
||||
transformImageBitmap((ImageView) child, t, 0);
|
||||
} else {
|
||||
rotationAngle = (int) ((float) (mCoveflowCenter - childCenter)
|
||||
/ childWidth * mMaxRotationAngle);
|
||||
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
|
||||
rotationAngle = rotationAngle < 0 ? -mMaxRotationAngle
|
||||
: mMaxRotationAngle;
|
||||
}
|
||||
transformImageBitmap((ImageView) child, t, rotationAngle);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called during layout when the size of this view has changed. If
|
||||
* you were just added to the view hierarchy, you're called with the old
|
||||
* values of 0.
|
||||
*
|
||||
* @param w
|
||||
* Current width of this view.
|
||||
* @param h
|
||||
* Current height of this view.
|
||||
* @param oldw
|
||||
* Old width of this view.
|
||||
* @param oldh
|
||||
* Old height of this view.
|
||||
*/
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw,
|
||||
final int oldh) {
|
||||
mCoveflowCenter = getCenterOfCoverflow();
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
/**
|
||||
* This is called during layout when the size of this view has changed. If
|
||||
* you were just added to the view hierarchy, you're called with the old
|
||||
* values of 0.
|
||||
*
|
||||
* @param w
|
||||
* Current width of this view.
|
||||
* @param h
|
||||
* Current height of this view.
|
||||
* @param oldw
|
||||
* Old width of this view.
|
||||
* @param oldh
|
||||
* Old height of this view.
|
||||
*/
|
||||
@Override
|
||||
protected void onSizeChanged(final int w, final int h, final int oldw,
|
||||
final int oldh) {
|
||||
mCoveflowCenter = getCenterOfCoverflow();
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the Image Bitmap by the Angle passed.
|
||||
*
|
||||
* @param imageView
|
||||
* ImageView the ImageView whose bitmap we want to rotate
|
||||
* @param t
|
||||
* transformation
|
||||
* @param rotationAngle
|
||||
* the Angle by which to rotate the Bitmap
|
||||
*/
|
||||
private void transformImageBitmap(final ImageView child,
|
||||
final Transformation t, final int rotationAngle) {
|
||||
mCamera.save();
|
||||
final Matrix imageMatrix = t.getMatrix();
|
||||
/**
|
||||
* Transform the Image Bitmap by the Angle passed.
|
||||
*
|
||||
* @param imageView
|
||||
* ImageView the ImageView whose bitmap we want to rotate
|
||||
* @param t
|
||||
* transformation
|
||||
* @param rotationAngle
|
||||
* the Angle by which to rotate the Bitmap
|
||||
*/
|
||||
private void transformImageBitmap(final ImageView child,
|
||||
final Transformation t, final int rotationAngle) {
|
||||
mCamera.save();
|
||||
final Matrix imageMatrix = t.getMatrix();
|
||||
|
||||
final int height = child.getLayoutParams().height;
|
||||
final int height = child.getLayoutParams().height;
|
||||
|
||||
final int width = child.getLayoutParams().width;
|
||||
final int rotation = Math.abs(rotationAngle);
|
||||
final int width = child.getLayoutParams().width;
|
||||
final int rotation = Math.abs(rotationAngle);
|
||||
|
||||
mCamera.translate(0.0f, 0.0f, 100.0f);
|
||||
mCamera.translate(0.0f, 0.0f, 100.0f);
|
||||
|
||||
// As the angle of the view gets less, zoom in
|
||||
if (rotation < mMaxRotationAngle) {
|
||||
final float zoomAmount = (float) (mMaxZoom + rotation * 1.5);
|
||||
mCamera.translate(0.0f, 0.0f, zoomAmount);
|
||||
}
|
||||
// As the angle of the view gets less, zoom in
|
||||
if (rotation < mMaxRotationAngle) {
|
||||
final float zoomAmount = (float) (mMaxZoom + rotation * 1.5);
|
||||
mCamera.translate(0.0f, 0.0f, zoomAmount);
|
||||
}
|
||||
|
||||
mCamera.rotateY(rotationAngle);
|
||||
mCamera.getMatrix(imageMatrix);
|
||||
imageMatrix.preTranslate(-(width / 2.0f), -(height / 2.0f));
|
||||
imageMatrix.postTranslate((width / 2.0f), (height / 2.0f));
|
||||
mCamera.restore();
|
||||
}
|
||||
mCamera.rotateY(rotationAngle);
|
||||
mCamera.getMatrix(imageMatrix);
|
||||
imageMatrix.preTranslate(-(width / 2.0f), -(height / 2.0f));
|
||||
imageMatrix.postTranslate((width / 2.0f), (height / 2.0f));
|
||||
mCamera.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the attributes.
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param attrs
|
||||
* the attrs
|
||||
*/
|
||||
private void parseAttributes(final Context context, final AttributeSet attrs) {
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.CoverFlow);
|
||||
try {
|
||||
imageWidth = a.getDimension(R.styleable.CoverFlow_imageWidth, 480);
|
||||
imageHeight = a.getDimension(R.styleable.CoverFlow_imageHeight, 320);
|
||||
withReflection = a.getBoolean(R.styleable.CoverFlow_withReflection,
|
||||
false);
|
||||
imageReflectionRatio = a.getFloat(
|
||||
R.styleable.CoverFlow_imageReflectionRatio, 0.2f);
|
||||
reflectionGap = a.getDimension(R.styleable.CoverFlow_reflectionGap,
|
||||
4);
|
||||
setSpacing(-15);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Parses the attributes.
|
||||
*
|
||||
* @param context
|
||||
* the context
|
||||
* @param attrs
|
||||
* the attrs
|
||||
*/
|
||||
private void parseAttributes(final Context context, final AttributeSet attrs) {
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.CoverFlow);
|
||||
try {
|
||||
imageWidth = a.getDimension(R.styleable.CoverFlow_imageWidth, 480);
|
||||
imageHeight = a.getDimension(R.styleable.CoverFlow_imageHeight, 320);
|
||||
withReflection = a.getBoolean(R.styleable.CoverFlow_withReflection,
|
||||
false);
|
||||
imageReflectionRatio = a.getFloat(
|
||||
R.styleable.CoverFlow_imageReflectionRatio, 0.2f);
|
||||
reflectionGap = a.getDimension(R.styleable.CoverFlow_reflectionGap,
|
||||
4);
|
||||
setSpacing(-15);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user