仿旋转木马控件

本文详细介绍了如何创建一个仿旋转木马效果的用户界面控件,包括控件的设计理念、实现原理和关键代码片段,帮助开发者在应用程序中实现独特的视觉交互体验。
摘要由CSDN通过智能技术生成
/*
 * Copyright (C) 2012 www.amsoft.cn
 *
 * 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 com.up72.football.widget.rotate;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.animation.Transformation;

import com.up72.football.R;
import com.up72.football.widget.rotate.woodenutils.AbImageUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

// TODO: Auto-generated Javadoc

public class CarouselImageView extends CarouselSpinner implements GestureDetector.OnGestureListener {


    // Static private members

    /**
     * Tag for a class logging.
     */
    private static final String TAG = CarouselImageView.class.getSimpleName();

    /**
     * If logging should be inside class.
     */
    private static final boolean localLOGV = false;

    /**
     * Default min quantity of images.
     */
    private static final int MIN_QUANTITY = 3;

    /**
     * Default max quantity of images.
     */
    private static final int MAX_QUANTITY = 12;

    /**
     * Max theta.
     */
    private static final float MAX_THETA = 15.0f;

    /**
     * Duration in milliseconds from the start of a scroll during which we're
     * unsure whether the user is scrolling or flinging.
     */
    private static final int SCROLL_TO_FLING_UNCERTAINTY_TIMEOUT = 250;

    // Private members

    /**
     * The info for adapter context menu.
     */
    private AdapterContextMenuInfo mContextMenuInfo;

    /**
     * How long the transition animation should run when a child view changes
     * position, measured in milliseconds.
     */
    private int mAnimationDuration = 900;

    /**
     * Camera to make 3D rotation.
     */
    private Camera mCamera = new Camera();

    /**
     * Sets mSuppressSelectionChanged = false. This is used to set it to false
     * in the future. It will also trigger a selection changed.
     */
    private Runnable mDisableSuppressSelectionChangedRunnable = new Runnable() {
        public void run() {
            mSuppressSelectionChanged = false;
            selectionChanged();
        }
    };

    /**
     * The position of the item that received the user's down touch.
     */
    private int mDownTouchPosition;

    /**
     * The view of the item that received the user's down touch.
     */
    private View mDownTouchView;

    /**
     * Executes the delta rotations from a fling or scroll movement.
     */
    public FlingRotateRunnable mFlingRunnable = new FlingRotateRunnable();

    /**
     * Helper for detecting touch gestures.
     */
    private GestureDetector mGestureDetector;

    /**
     * Gravity for the widget.
     */
    private int mGravity;

    /**
     * If true, this onScroll is the first for this user's drag (remember, a
     * drag sends many onScrolls).
     */
    private boolean mIsFirstScroll;

    /**
     * Set max qantity of images.
     */
    private int mMaxQuantity = MAX_QUANTITY;

    /**
     * Set min quantity of images.
     */
    private int mMinQuantity = MIN_QUANTITY;

    /**
     * If true, we have received the "invoke" (center or enter buttons) key
     * down. This is checked before we action on the "invoke" key up, and is
     * subsequently cleared.
     */
    private boolean mReceivedInvokeKeyDown;

    /**
     * The currently selected item's child.
     */
    private View mSelectedChild;


    /**
     * Whether to continuously callback on the item selected listener during a
     * fling.
     */
    private boolean mShouldCallbackDuringFling = true;

    /**
     * Whether to callback when an item that is not selected is clicked.
     */
    private boolean mShouldCallbackOnUnselectedItemClick = true;

    /**
     * When fling runnable runs, it resets this to false. Any method along the
     * path until the end of its run() can set this to true to abort any
     * remaining fling. For example, if we've reached either the leftmost or
     * rightmost item, we will set this to true.
     */
    private boolean mShouldStopFling;

    /**
     * If true, do not callback to item selected listener.
     */
    private boolean mSuppressSelectionChanged;

    /**
     * The axe angle. 设置圆的直径
     * chenzefeng
     */
    private float mTheta = (float) (20.0f * (Math.PI / 50.0));

    /**
     * If items should be reflected.
     */
    private boolean mUseReflection;

    // Constructors

    /**
     * Instantiates a new carousel image view.
     *
     * @param context the context
     */
    public CarouselImageView(Context context) {
        this(context, null);
    }

    /**
     * Instantiates a new carousel image view.
     *
     * @param context the context
     * @param attrs   the attrs
     */
    public CarouselImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    private Paint paint;
    private float screenWidth, screenHeight;

    /**
     * Instantiates a new carousel image view.
     *
     * @param context  the context
     * @param attrs    the attrs
     * @param defStyle the def style
     */
    public CarouselImageView(Context context, AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
        paint = new Paint();
        paint.setColor(Color.RED);
//        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(20);

        // It's needed to make items with greater value of
        // z coordinate to be behind items with lesser z-coordinate
        setChildrenDrawingOrderEnabled(true);

        // Making user gestures available
        mGestureDetector = new GestureDetector(this.getContext(), this);
        mGestureDetector.setIsLongpressEnabled(true);

        // It's needed to apply 3D transforms to items
        // before they are drawn
        setStaticTransformationsEnabled(true);

        // Retrieve settings
        mAnimationDuration = 400;
        mUseReflection = false;
        int selectedItem = 0;

        // next time we go through layout with this value
        setNextSelectedPositionInt(selectedItem);

        WindowManager wm = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);

        screenWidth = wm.getDefaultDisplay().getWidth();
        screenHeight = wm.getDefaultDisplay().getHeight();
        newScreenHeight = (int) (screenHeight / 2);
        newScreenWidth = (int) (screenWidth / 2);
        coreX = newScreenWidth / 2;
        coreY = newScreenHeight / 2;
    }

    int newScreenHeight, newScreenWidth, coreX, coreY;

    /**
     * 绘制位图
     * chenzefeng
     *
     * @param canvas
     */
    @Override
    protected void onDraw(Canvas canvas) {
        //功能三
        if (width > 0 | height > 0) {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_border);
            int a = 150;
            int b = a / 2;
            int value = (int) height + 20;
            int location = (int) ((value - width) / 2);        //准确计算出图片在边框的中心位置
            bitmap = AbImageUtil.zoomImg(bitmap, value - a, value - a);//以高度为准计算出位图的大小
            // 绘图
            canvas.drawBitmap(bitmap, x - location + b, (Math.abs(y) - 0 * 2) + b, paint);//设置位置   y-0之前是  -20
        }
    }
    // View overrides

    // These are for use with horizontal scrollbar

    /**
     * Compute the horizontal extent of the horizontal scrollbar's thumb
     * within the horizontal range. This value is used to compute
     * the length of the thumb within the scrollbar's track.
     *
     * @return the int
     */
    @Override
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值