華夏萬象 Android 版 widget 庫

這個庫在「華夏萬象」Android 版開發過程當中產出,僅用作查閱參考、不適合工業使用。java

目錄

  1. MarqueeDrawable 跑馬燈進度條 drawable
  2. StarrySky 星空 drawable
  3. ChinaMapView 中國地圖帶手勢版本
  4. MenuItemView 帶底部菜單的View
  5. ParallaxRelativeLayout 縱向的視差滾動佈局
  6. SegmentProgressBar 分段、可拖動的進度條
  7. VerticalTextView 縱向 TextView
  8. ShapedImageView 可控制寬高比的 ImageView
  9. com.antiless.huaxia.widget.gesture 一個易於擴展的手勢檢測框架

用法

1. MarqueeDrawable

/**
 * 跑馬燈進度條 drawable
 * @param width 指望寬度 Pixel
 * @param height 指望高度 Pixel
 * @param perWidth 跑馬燈每段寬度 Pixel
 */
class MarqueeDrawable(val width: Int, val height: Int, val perWidth: Int) : Drawable(), Animatable

val marqueeDrawable = MarqueeDrawable(width, height, perWidth)
ImageView.setImageDrawable(marqueeDrawable)
marqueeDrawable.progress = 50

2. StarrySky

星空 Drawablenode

/**
* 星空 drawable
* @param widthPixels 寬度
* @param heightPixels 高度
*/
class StarrySky(val widthPixels: Int, val heightPixels: Int) : Drawable(), Animatable


val starrySky = StarrySky(widthPixels, heightPixels).apply {
    for (i in 0 until 50) {
        // 添加 50 個隨機位置的星星
        addRandomStar()
    }
    // 監聽星星跑出範圍
    setOnStarOutListener {
        removeStar(it)
        addRandomStar()
    }
}
ImageView.setImageDrawable(starrySky)
// 開始運動
starrySky.start()
// 中止運動
starrySky.stop()
  1. ChinaMapView

中國地圖帶手勢版本android

這個控件基於ChinaMapView
加入了雙指操做手勢,雙指基於第 9 項的手勢檢測框架git

<com.antiless.huaxia.widget.chinamap.ChinaMapView
    android:id="@+id/itemMap"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
/**
* 添加不可選區域
*/
void addUnSelectableArea(Area area)
/**
* 設置選中監聽
*/
void setOnProvinceSelectedListener(OnProvinceSelectedListener pOnProvinceSelectedListener)
/**
* 設置空白處雙擊監聽
*/
void setOnProvinceDoubleClickListener(OnProvinceDoubleClickListener onDoubleClickListener)
/**
* 設置區域繪製 paint.style 是否爲 Paint.Style.FILL
*/
void setPaintColor(Area pArea, int color, boolean isFull)
  1. MenuItemView

帶底部菜單的View, 手勢左滑展現底部菜單github

<com.antiless.huaxia.widget.MenuItemView
        android:id="@+id/menuItemView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:backViewId="@id/itemMenu"
        app:coverViewId="@id/itemCover"
        app:dragEnable="true">
        <View android:id="@+id/itemMenu"/>
        <View android:id="@+id/itemOver"/>
</com.antiless.huaxia.widget.MenuItemView>
fun showBackView()
fun resetBackView()
fun isBackShowed(): Boolean
  1. ParallaxRelativeLayout

縱向的視差滾動佈局app

只有一個參數layout_parallax_speed,值爲1時正常速度滾動,值 0~1 時小於正常速度滾動,>1 時大於正常速度滾動框架

<ScrollView>
    <com.antiless.huaxia.widget.ParallaxRelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <View app:layout_parallax_speed="0.6"/>
            <View app:layout_parallax_speed="1"/>
            <View app:layout_parallax_speed="1.6"/>
    </com.antiless.huaxia.widget.ParallaxRelativeLayout>
</ScrollView>
  1. SegmentProgressBar

分段、可拖動的進度條less

<com.antiless.huaxia.widget.SegmentProgressBar
    android:id="@+id/segmentProgressBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
maxSegment  最大值
minSegment  最小值
currentSegment  當前值
showBubble()    顯示氣泡
hideBubble()    隱藏氣泡
bubbleAnimating  氣泡是否在動畫中
  1. VerticalTextView

縱向 TextViewdom

<com.antiless.huaxia.widget.VerticalTextView
    android:text="xxx"
    android:textSize="xxx"
    android:textColor="xxx"
    android:height="textStyle"
    android:letterSpace="height"
    android:textStyle="letterSpace"
/>
<declare-styleable name="VerticalTextView">
    <attr name="text"/>
    <attr name="textSize"/>
    <attr name="textColor"/>
    <attr name="height" format="dimension"/>
    <attr name="letterSpace" format="float"/>
    <attr name="textStyle"/>
</declare-styleable>
  1. ShapedImageView

可控制寬高比的 ImageViewide

<com.antiless.huaxia.widget.ShapedImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    app:base="widthBased"
    app:heightWeight="1"
    app:radius="4dp"
    app:widthWeight="1" />

<declare-styleable name="ShapedImageView">
    <attr name="widthWeight" format="integer"/>
    <attr name="heightWeight" format="integer"/>
    <attr name="radius" format="dimension"/>
    <attr name="strokeColor" format="color"/>
    <attr name="strokeWidth" format="dimension"/>
    <attr name="base">
        <enum name="heightBased" value="0" />
        <enum name="widthBased" value="1" />
    </attr>
</declare-styleable>
  1. com.antiless.huaxia.widget.gesture

一個易於擴展的手勢檢測框架

使用方法很簡單:

DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
GesturePointersUtility utility = new GesturePointersUtility(dm);
transformSystem = new TransformSystem(dm, utility);
TransformNode node = new TransformNode(this, transformSystem);

// 內置了單指滑動、雙指pinch、雙指拖動、雙指twist手勢識別
// 開發者可自定義手勢識別邏輯,註冊到TransformSystem中
// 而後實現BaseTransformationController, 將手勢識別的結果反應到指定的對象上
// 最後在 TransformNode 中註冊本身實現的 Controller

1. 實現 controller

Controller 用於將手勢行爲的結果應用到 View 上

ScaleController 是將pinch手勢的結果用來縮放

class ScaleController(transformNode: BaseTransformNode, recognizer: PinchGestureRecognizer) : BaseTransformationController<PinchGesture>(transformNode, recognizer) {
    override fun canStartTransformation(gesture: PinchGesture): Boolean {
        return true
    }

    var lastRatio = 1f
    override fun onContinueTransformation(gesture: PinchGesture) {
        if (transformNode.view is ChinaMapView) {
            val pinchRatio = gesture.gap / gesture.startGap
            val startCenterPoint = gesture.startPosition1.center(gesture.startPosition2)
            val scale = pinchRatio / lastRatio
            lastRatio = pinchRatio
            transformNode.view.scale(scale, startCenterPoint.x, startCenterPoint.y)
        }
    }

    override fun onEndTransformation(gesture: PinchGesture) {
        lastRatio = 1f
    }
}

2. 註冊 controller
聲明須要使用的 controller

該例中:
雙指 pinch 縮放
雙指滑動進行拖動
雙指 twist 進行平面旋轉
單指滑動旋轉 3d 視角

class TransformNode(view: View, transformSystem: TransformSystem) : BaseTransformNode(view, transformSystem) {
    private val scaleController: ScaleController = ScaleController(this, transformSystem.pinchGestureRecognizer)
    private val dragController: DragController = DragController(this, transformSystem.doubleFingerMoveGestureRecognizer)
    private val rotateController: RotateController = RotateController(this, transformSystem.twistGestureRecognizer)
    private val visualController: VisualController = VisualController(this, transformSystem.swipeGestureRecognizer)

    init {
        addTransformationController(dragController)
        addTransformationController(scaleController)
        addTransformationController(rotateController)
        addTransformationController(visualController)
    }
}

3. 自定義你的手勢識別器

  1. 實現 BaseGestureBaseGestureRecognizer
  2. 使用 TransformSystem.addGestureRecognizer() 註冊 YourRecognizer
  3. 實現 BaseTransformationController<YourGesture>(TransformNode, YourRecognizer)
  4. 使用 TransformNode.addTransformationController 註冊 YourController

4. 在須要使用手勢識別的地方調用

DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
GesturePointersUtility utility = new GesturePointersUtility(dm);
transformSystem = new TransformSystem(dm, utility);
TransformNode node = new TransformNode(this, transformSystem);

歡迎關注個人主頁

Github源碼

Github主頁

個人博客

相關文章
相關標籤/搜索