Android Open Source - opentraining Fancy Cover Flow Item Wrapper






From Project

Back to project page opentraining.

License

The source code is released under:

GNU General Public License

If you think the Android project opentraining listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2013 David Schreiber/*  ww  w.j a  v  a2s. c o m*/
 *           2013 John Paul Nalog
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package at.technikum.mti.fancycoverflow;

import android.*;
import android.R;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.*;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * This class has only internal use (package scope).
 * <p/>
 * It is responsible for applying additional effects to each coverflow item, that can only be applied at view level
 * (e.g. color saturation).
 * <p/>
 * This is a ViewGroup by intention to enable child views in layouts to stay interactive (like buttons) though
 * transformed.
 * <p/>
 * Since this class is only used within the FancyCoverFlowAdapter it doesn't need to check if there are multiple
 * children or not (there can only be one at all times).
 */
@SuppressWarnings("ConstantConditions")
class FancyCoverFlowItemWrapper extends ViewGroup {

    // =============================================================================
    // Private members
    // =============================================================================

    private float saturation;

    private boolean isReflectionEnabled = false;

    private float imageReflectionRatio;

    private int reflectionGap;

    private float originalScaledownFactor;

    /**
     * This is a matrix to apply color filters (like saturation) to the wrapped view.
     */
    private ColorMatrix colorMatrix;

    /**
     * This paint is used to draw the wrapped view including any filters.
     */
    private Paint paint;

    /**
     * This is a cache holding the wrapped view's visual representation.
     */
    private Bitmap wrappedViewBitmap;

    /**
     * This canvas is used to let the wrapped view draw it's content.
     */
    private Canvas wrappedViewDrawingCanvas;


    // =============================================================================
    // Constructor
    // =============================================================================

    public FancyCoverFlowItemWrapper(Context context) {
        super(context);
        this.init();
    }

    public FancyCoverFlowItemWrapper(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.init();
    }

    public FancyCoverFlowItemWrapper(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.init();
    }

    private void init() {
        this.paint = new Paint();
        this.colorMatrix = new ColorMatrix();
        // TODO: Define a default value for saturation inside an XML.
        this.setSaturation(1);
    }

    // =============================================================================
    // Getters / Setters
    // =============================================================================

    @SuppressLint("NewApi")
  void setReflectionEnabled(boolean hasReflection) {
        if (hasReflection != this.isReflectionEnabled) {
            this.isReflectionEnabled = hasReflection;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                // Turn off hardware acceleration if necessary (reflections won't support it).
                this.setLayerType(hasReflection ? View.LAYER_TYPE_SOFTWARE : View.LAYER_TYPE_HARDWARE, null);
            }

            this.remeasureChildren();
        }
    }

    void setReflectionRatio(float imageReflectionRatio) {
        if (imageReflectionRatio != this.imageReflectionRatio) {
            this.imageReflectionRatio = imageReflectionRatio;
            this.remeasureChildren();
        }
    }

    void setReflectionGap(int reflectionGap) {
        if (reflectionGap != this.reflectionGap) {
            this.reflectionGap = reflectionGap;
            this.remeasureChildren();
        }
    }

    public void setSaturation(float saturation) {
        if (saturation != this.saturation) {
            this.saturation = saturation;
            this.colorMatrix.setSaturation(saturation);
            this.paint.setColorFilter(new ColorMatrixColorFilter(this.colorMatrix));
        }
    }

    // =============================================================================
    // Supertype overrides
    // =============================================================================

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        this.remeasureChildren();

        // If we have reflection enabled, the original image is scaled down and a reflection is added beneath. Thus,
        // while maintaining the same height the width decreases and we need to adjust measured width.
        // WARNING: This is a hack because we do not obey the EXACTLY MeasureSpec mode that we will get mostly.
        if (this.isReflectionEnabled) {
            this.setMeasuredDimension((int) (this.getMeasuredWidth() * this.originalScaledownFactor), this.getMeasuredHeight());
        }
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed) {
            int measuredWidth = this.getMeasuredWidth();
            int measuredHeight = this.getMeasuredHeight();

            if (this.wrappedViewBitmap == null || this.wrappedViewBitmap.getWidth() != measuredWidth || this.wrappedViewBitmap.getHeight() != measuredHeight) {
                this.wrappedViewBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
                this.wrappedViewDrawingCanvas = new Canvas(this.wrappedViewBitmap);
            }

            View child = getChildAt(0);
            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();
            int childLeft = (measuredWidth - childWidth) / 2;
            int childRight = measuredWidth - childLeft;
            child.layout(childLeft, 0, childRight, childHeight);
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    protected void dispatchDraw(Canvas canvas) {
        View childView = getChildAt(0);

        if (childView != null) {
            // If on honeycomb or newer, cache the view.
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                if (childView.isDirty()) {
                    childView.draw(this.wrappedViewDrawingCanvas);

                    if (this.isReflectionEnabled) {
                        this.createReflectedImages();
                    }
                }
            } else {
                childView.draw(this.wrappedViewDrawingCanvas);
            }
        }

        canvas.drawBitmap(this.wrappedViewBitmap, (this.getWidth() - childView.getWidth()) / 2, 0, paint);
    }

    // =============================================================================
    // Methods
    // =============================================================================

    private void remeasureChildren() {
        View child = this.getChildAt(0);

        if (child != null) {
            // When reflection is enabled calculate proportional scale down factor.
            final int originalChildHeight = this.getMeasuredHeight();
            this.originalScaledownFactor = this.isReflectionEnabled ? (originalChildHeight * (1 - this.imageReflectionRatio) - reflectionGap) / originalChildHeight : 1.0f;
            final int childHeight = (int) (this.originalScaledownFactor * originalChildHeight);
            final int childWidth = (int) (this.originalScaledownFactor * getMeasuredWidth());

            int heightSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST);
            int widthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
            this.getChildAt(0).measure(widthSpec, heightSpec);
        }
    }

    /**
     * Creates the reflected images.
     *
     * @return true, if successful
     */
    private void createReflectedImages() {

        final int width = this.wrappedViewBitmap.getWidth();
        final int height = this.wrappedViewBitmap.getHeight();


        final Matrix matrix = new Matrix();
        matrix.postScale(1, -1);


        final int scaledDownHeight = (int) (height * originalScaledownFactor);
        final int invertedHeight = height - scaledDownHeight - reflectionGap;
        final int invertedBitmapSourceTop = scaledDownHeight - invertedHeight;
        final Bitmap invertedBitmap = Bitmap.createBitmap(this.wrappedViewBitmap, 0, invertedBitmapSourceTop, width, invertedHeight, matrix, true);

        this.wrappedViewDrawingCanvas.drawBitmap(invertedBitmap, 0, scaledDownHeight + reflectionGap, null);

        final Paint paint = new Paint();
        final LinearGradient shader = new LinearGradient(0, height * imageReflectionRatio + reflectionGap, 0, height, 0x70ffffff, 0x00ffffff, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        this.wrappedViewDrawingCanvas.drawRect(0, height * (1 - imageReflectionRatio), width, height, paint);
    }
}




Java Source Code List

at.technikum.mti.fancycoverflow.FancyCoverFlowAdapter.java
at.technikum.mti.fancycoverflow.FancyCoverFlowItemWrapper.java
at.technikum.mti.fancycoverflow.FancyCoverFlow.java
de.skubware.opentraining.activity.ChangeLogDialog.java
de.skubware.opentraining.activity.DisclaimerDialog.java
de.skubware.opentraining.activity.MainActivity.java
de.skubware.opentraining.activity.NavigationGalleryAdapter.java
de.skubware.opentraining.activity.SelectWorkoutDialogFragment.java
de.skubware.opentraining.activity.WhatsNewDialog.java
de.skubware.opentraining.activity.acra.ACRACrashReportMailer.java
de.skubware.opentraining.activity.acra.ACRAFeedbackMailer.java
de.skubware.opentraining.activity.acra.OpenTrainingApplication.java
de.skubware.opentraining.activity.acra.RequestExerciseUpdate.java
de.skubware.opentraining.activity.create_exercise.CreateExerciseActivity.java
de.skubware.opentraining.activity.create_exercise.CustomSpinner.java
de.skubware.opentraining.activity.create_exercise.DescriptionFragment.java
de.skubware.opentraining.activity.create_exercise.EditImageMetadataDialog.java
de.skubware.opentraining.activity.create_exercise.EquipmentDataFragment.java
de.skubware.opentraining.activity.create_exercise.ExerciseImageListAdapter.java
de.skubware.opentraining.activity.create_exercise.ImageFragment.java
de.skubware.opentraining.activity.create_exercise.MuscleDataFragment.java
de.skubware.opentraining.activity.create_exercise.NameFragment.java
de.skubware.opentraining.activity.create_exercise.SimpleDataFragment.java
de.skubware.opentraining.activity.create_exercise.SpinnerDataFragment.java
de.skubware.opentraining.activity.create_workout.DialogFilterMusclesAndEquipment.java
de.skubware.opentraining.activity.create_workout.DialogWorkoutOverviewFragment.java
de.skubware.opentraining.activity.create_workout.ExerciseDetailOnGestureListener.java
de.skubware.opentraining.activity.create_workout.ExerciseTypeDetailActivity.java
de.skubware.opentraining.activity.create_workout.ExerciseTypeDetailFragment.java
de.skubware.opentraining.activity.create_workout.ExerciseTypeListActivity.java
de.skubware.opentraining.activity.create_workout.ExerciseTypeListAdapter.java
de.skubware.opentraining.activity.create_workout.ExerciseTypeListFragment.java
de.skubware.opentraining.activity.create_workout.SelectMuscleDialog.java
de.skubware.opentraining.activity.create_workout.SendExerciseFeedbackDialogFragment.java
de.skubware.opentraining.activity.create_workout.upload_exercise.ExerciseImage.java
de.skubware.opentraining.activity.create_workout.upload_exercise.UploadExerciseAsyncTask.java
de.skubware.opentraining.activity.create_workout.upload_exercise.UploadExerciseImagesAsyncTask.java
de.skubware.opentraining.activity.create_workout.upload_exercise.WgerRestService.java
de.skubware.opentraining.activity.manage_workouts.RenameWorkoutDialogFragment.java
de.skubware.opentraining.activity.manage_workouts.WorkoutDetailActivity.java
de.skubware.opentraining.activity.manage_workouts.WorkoutDetailFragment.java
de.skubware.opentraining.activity.manage_workouts.WorkoutListActivity.java
de.skubware.opentraining.activity.manage_workouts.WorkoutListFragment.java
de.skubware.opentraining.activity.settings.LicenseDialog.java
de.skubware.opentraining.activity.settings.SettingsActivity.java
de.skubware.opentraining.activity.settings.sync.OpenTrainingSyncResultReceiver.java
de.skubware.opentraining.activity.settings.sync.OpenTrainingSyncService.java
de.skubware.opentraining.activity.settings.sync.RestClient.java
de.skubware.opentraining.activity.settings.sync.SyncFinishedDialog.java
de.skubware.opentraining.activity.settings.sync.WgerImageDownloader.java
de.skubware.opentraining.activity.settings.sync.WgerJSONParser.java
de.skubware.opentraining.activity.start_training.DialogFragmentAddEntry.java
de.skubware.opentraining.activity.start_training.DialogFragmentTrainingEntryTable.java
de.skubware.opentraining.activity.start_training.FExDetailActivity.java
de.skubware.opentraining.activity.start_training.FExDetailFragment.java
de.skubware.opentraining.activity.start_training.FExListActivity.java
de.skubware.opentraining.activity.start_training.FExListAdapter.java
de.skubware.opentraining.activity.start_training.FExListFragment.java
de.skubware.opentraining.activity.start_training.RecoveryTimerManager.java
de.skubware.opentraining.activity.start_training.SwipeDismissListViewTouchListener.java
de.skubware.opentraining.activity.start_training.SwipeDismissTouchListener.java
de.skubware.opentraining.activity.start_training.TrainingEntryListAdapter.java
de.skubware.opentraining.basic.ActivationLevel.java
de.skubware.opentraining.basic.ExerciseTag.java
de.skubware.opentraining.basic.ExerciseType.java
de.skubware.opentraining.basic.FSet.java
de.skubware.opentraining.basic.FitnessExercise.java
de.skubware.opentraining.basic.IExercise.java
de.skubware.opentraining.basic.License.java
de.skubware.opentraining.basic.Muscle.java
de.skubware.opentraining.basic.SportsEquipment.java
de.skubware.opentraining.basic.TrainingEntry.java
de.skubware.opentraining.basic.Translatable.java
de.skubware.opentraining.basic.Workout.java
de.skubware.opentraining.db.Cache.java
de.skubware.opentraining.db.DataHelper.java
de.skubware.opentraining.db.DataProvider.java
de.skubware.opentraining.db.IDataProvider.java
de.skubware.opentraining.db.parser.AbstractJSONParser.java
de.skubware.opentraining.db.parser.ExerciseTagJSONParser.java
de.skubware.opentraining.db.parser.ExerciseTypeXMLParser.java
de.skubware.opentraining.db.parser.IParser.java
de.skubware.opentraining.db.parser.MuscleJSONParser.java
de.skubware.opentraining.db.parser.SportsEquipmentJSONParser.java
de.skubware.opentraining.db.parser.WorkoutXMLParser.java
de.skubware.opentraining.db.parser.XMLSaver.java
de.skubware.opentraining.db.rest.ExerciseImageGSONSerializer.java
de.skubware.opentraining.db.rest.ExerciseTypeGSONSerializer.java
de.skubware.opentraining.db.rest.LanguageGSONDeserializer.java
de.skubware.opentraining.db.rest.MuscleGSONDeserializer.java
de.skubware.opentraining.db.rest.ServerModel.java
de.skubware.opentraining.db.rest.SportsEquipmentGSONDeserializer.java
de.skubware.opentraining.exporter.HTMLExporter.java
de.skubware.opentraining.exporter.LaTeXExporter.java
de.skubware.opentraining.exporter.WorkoutExporter.java