1. 程式人生 > >【Android自定義控制元件】之仿網易星球浮動小球

【Android自定義控制元件】之仿網易星球浮動小球

仿網易星球浮動小球

讀唄開發過程中遇到新需求,類似於網易星球收集黑鑽的介面,考慮到可能也有人會使用,索性封裝成庫,後面好移植使用

先看看需要實現的效果:
網易星球

需求分析:

  1. 資料集合可能是int、double、float等型別
  2. 小球位置隨機
  3. 沒有資料時只有一個預設小球,位置固定
  4. 小球上下抖動,點擊向上運動消失

實現分析:

  1. 小球隨機的位置固定在父view的寬高範圍內
  2. 可以在初始化和點選時判斷集合是否為空從而顯示預設小球
  3. 補間動畫實現抖動、屬性動畫實現點選上滑消失(純屬個人習慣,沒有規定動畫型別)

實現步驟:

FloatView

父控制元件使用Relativelayout(背景可以先指定,後面已經抽取出來可以自定義)

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@mipmap/star_bg">
</RelativeLayout>

parentView

小球佈局

<TextView
    android:id="@+id/float_view"
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:gravity="center"
    android:text="0.01234"
    android:textSize="6dp"
    android:textColor="#ffffff"
    android:background="@drawable/shape_circle">
</TextView>

子控制元件

上面佈局都是暫定的,後面封裝的時候都保留了介面

1、定義構造方法

 public FloatView(Context context) {
       this(context,null);
       mcontext = context;
     }

 public FloatView(Context context, AttributeSet attrs) {
       super(context, attrs);
       mcontext = context;  
     }

public FloatView(Context context, AttributeSet attrs, int defStyleAttr) {
       this(context, attrs);
       mcontext = context;
    }

2、初始化預設小球

LayoutParams params = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
defaultView = (TextView) LayoutInflater.from(mcontext).inflate(R.layout.view_float, this, false); params.addRule(RelativeLayout.CENTER_IN_PARENT);       
if (mFloat.size() != 0){
    defaultView.setVisibility(GONE);
}
addView(defaultView,params);

3、設定子view位置並新增

子View座標分析

  1. 子View隨機座標範圍(保證不能出parentView的邊界)

        Random randomX = new Random();
        Random randomY = new Random();
        float x = randomX.nextFloat() * (parentWidth - childView.getMeasuredWidth());
        float y = randomY.nextFloat() * (parentHeight - childView.getMeasuredHeight());
        childView.setX(x);
        childView.setY(y);
    
  2. 新增子View

    for (int i = 0; i < mFloat.size(); i++) {
        TextView floatview = (TextView) LayoutInflater.from(mcontext).inflate(R.layout.view_float, this, false);
        setChildViewPosition(floatview);
        floatview.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        addView(floatview);
    }
    

5、設定子View抖動動畫

  Animation anim = new TranslateAnimation(0,0,-10,20);
  anim.setInterpolator(new AccelerateDecelerateInterpolator());
  anim.setDuration(ANIMATION_TIME);
  anim.setRepeatCount(Integer.MAX_VALUE);
  anim.setRepeatMode(Animation.REVERSE);//反方向執行
  view.startAnimation(anim);

6、點選移除(使用回撥介面暴露方法,並判斷是否是資料集合是否為空以顯示預設子View)

    alueAnimator animator = ValueAnimator.ofFloat(parentHeight,0);
    animator.setDuration(1000);
    animator.setInterpolator(new LinearInterpolator());
    //動畫更新的監聽
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float Value = (float) animation.getAnimatedValue();

            view.setAlpha(Value/parentHeight);
            view.setTranslationY(view.getY()-(parentHeight-Value));
        }
    });
    animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            removeView(view);
        }
    });
    animator.start();

設定回撥(詳情見原始碼):

  mListener.itemClick((int)view.getTag(),mFloat.get((int)view.getTag()));

實現效果圖:

完成效果圖

難點分析:

1、獲取的寬高為0?
view繪製過程中measure的時間和Activity的生命週期不能保持一致,所以可能在onCreate()中獲取的寬高為0;
解決辦法:使用post()

post(new Runnable() {
      @Override
       public void run() {
           init();
       }
});

2、子View的屬性為wrap_content,獲取的寬高為0,?
在獲取的寬高的時候,先指定測量規則

int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
parentView.measure(width,height);
parentHeight = parentView.getMeasuredHeight();
parentWidth = parentView.getMeasuredWidth();

3、傳輸資料固定?
這裡list使用Number型別的泛型,可以指定為int、float、double、long

public void setList(List<? extends Number> list){
    ...
    //回撥裡
    mListener.itemClick((int)view.getTag(),mFloat.get((int)view.getTag()));
}

封裝

使用方法:

在工程目錄的build.gradle中新增JitPack.io的程式碼倉庫地址

allprojects {
  repositories {
    ...
    maven { url 'https://jitpack.io' }
  }
}

專案目錄中的build.gradle中新增依賴

ependencies {
    compile 'com.github.ErChenZhang:StarFloatView:v1.1'
}

在佈局檔案中使用

     <com.smoke.zhangchen.floatviewlib.FloatView
        android:id="@+id/float_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content
        app:childTextColor="#ff0000"
        app:defaultViewText="正在生成中"
        app:chidTextSize="6sp"
        app:parentViewBackground="@mipmap/star_bg"
        app:childViewBackground="@drawable/shape_circle">
  1. childTextColor:小球文字顏色大小,預設白色
  2. defaultViewText:預設小球顯示文字
  3. parentViewBackground:整體背景
  4. childViewBackground:小球背景
  5. chidTextSize:小球文字大小,預設6sp

    設定資料

    當前資料支援int、long、float、double
     List<Float> list = new ArrayList<>();
        list.add((float) 1.245);
        list.add((float) 1.567);
        list.add((float) 0.261);
        floatview.setList(list);
    

小球點選回撥(value.floatValue()對應傳入的list型別)

floatview.setOnItemClickListener(new FloatView.OnItemClickListener() {
    @Override
     public void itemClick(int position, Number value) {
         Toast.makeText(MainActivity.this, "當前是第"+position+"個,其值是"+value.floatValue(), Toast.LENGTH_SHORT).show();
        }
});

相關推薦

Android定義控制元件仿星球浮動小球

仿網易星球浮動小球 讀唄開發過程中遇到新需求,類似於網易星球收集黑鑽的介面,考慮到可能也有人會使用,索性封裝成庫,後面好移植使用 先看看需要實現的效果: 需求分析: 資料集合可能是int、double、float等型別 小球位置隨機 沒有資料時

Android定義控制元件炫酷的底部導航欄

https://github.com/WakeHao/NavBar 基本使用 使用這個控制元件,只需要簡單的幾部 引入該控制元件到你的專案中 compile 'com.chen.wakehao.library:bottom-navigation-bar:1.0.0'

Android定義控制元件選擇輸入框的實現

1.場景 Android開發中經常會用到選擇輸入控制元件,比如性別的輸入 2.示例圖片 3.程式碼組成 1)演示用的主介面佈局不多說,這裡採用EditText + 一個自定義的底部列表對話方塊來實現的 2)佈局檔案 <?xml

Android定義控制元件仿IOS風格的搜尋框

IOS很多控制元件的設計都是很值得借鑑的存在,作為移動開發的初學者,我們可以把這種模仿等同於學畫、練字時為鑄就基礎的臨摹行為。達者為師,努力學習別人的優點吧。 這裡是仿IOS搜尋框風格的自定義控制元件,引用了http://blog.csdn.net/d

Android定義控制元件密碼輸入框+數字鍵盤的實現

因專案需要,實現了一個自定義的密輸入框和自定義數字鍵盤,用作使用者支付密碼設定介面。先上效果圖如下,方格樣式,以及點選空白處隱藏軟鍵盤。 控制元件實現清單: 1)集成於EditText的輸入框控制元件:PasswordInputView.java 2)

Android定義View實戰定義評價打分控制元件RatingBar,可以定義星星大小和間距

在Android開發中,我們經常會用到對商家或者商品的評價,運用星星進行打分。然而在Android系統中自帶的打分控制元件,RatingBar特別不好用,間距和大小無法改變。所以,我就自定義了一個特別好用的打分控制元件。在專案中可以直接使用,特別簡

Android定義View實戰定義超簡單SearchView搜尋框

package cn.bluemobi.dylan.searchview; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.util.A

Android定義控制元件-Path貝賽爾曲線和手勢軌跡、水波紋效果

從這篇開始,我將延續androidGraphics系列文章把圖片相關的知識給大家講完,這一篇先稍微進階一下,給大家把《android Graphics(二):路徑及文字》略去的quadTo(二階貝塞爾)函式,給大家補充一下。 本篇最終將以兩個例子給大家演示貝塞爾曲線

Android定義控制元件封裝定義屬性的實現

在開發中有時候我們需要去自定義一些組合控制元件,而在使用過程中,又想要自己的組合控制元件能有原生控制元件那樣可以在xml中使用屬性控制,那麼我們就需要去自定義一些屬性了 1:首先在values/attrs.xml中進行屬性的定義 <?xml version="1.

Android定義控制元件熱身scrollTo和scrollBy詳解

View通過ScrollTo和ScrollBy 方法可以實現滑動。那麼兩者有什麼區別呢?我們先來看一下原始碼 ScrollTo原始碼: public void scrollTo(int x,

Android定義控制元件實戰——實現仿IOS下拉重新整理上拉載入 PullToRefreshLayout

         下拉重新整理控制元件,網上有很多版本,有自定義Layout佈局的,也有封裝控制元件的,各種實現方式的都有。但是很少有人告訴你具體如何實現的,今天我們就來一步步實現自己封裝的 PullToRefreshLayout 完美的解決下拉重新整理,上拉載入問題。  

Android定義控制元件系列案例

案例效果: 模擬器上執行有些鋸齒,真機上和預期一樣好 案例分析: 看效果,第一直覺肯定是Android原生態控制元件中沒有這樣的控制元件實現這種效果,自然想到應該需要自定義控制元件了,沒錯,這就是通過自定義控制元件來繪製的一個圓環進度條。仔細分析發現這個效果的進度條應該

Android定義控制元件系列案例

Android自定義控制元件的重要性就不多說了,總之是技術進階,面試常見,高薪必備。 本篇博文的目的很簡單,就是希望通過自定義控制元件來解決一個常見需求點,從而感受一下自定義控制元件的魅力與強大。 案

Android定義控制元件區域性圖片放大鏡--BiggerView

零、前言: 本文的知識點一覽 1.自定義控制元件及自定義屬性的寫法,你也將對onMesure有更深的認識 2.關於bitmap的簡單處理,及canvas區域裁剪 3.本文會實現兩個自定義控制元件:FitImageView(圖片自適應)和BiggerView(放大鏡),前者為後者作為鋪墊。 4.最後會

Android定義控制元件仿汽車家下拉重新整理

關於下拉重新整理的實現原理我在上篇文章Android自定義控制元件之仿美團下拉重新整理中已經詳細介紹過了,這篇文章主要介紹錶盤的動畫實現原理 汽車之家的下拉重新整理分為三個狀態: 第一個狀態為下拉重新整理狀態(pull to refresh),在這個狀

Android定義控制元件《折線圖的繪製》

金融軟體裡的行情分時圖,這是我們最常見的折線圖,當然了,折線圖的用途並不僅僅侷限於此,像一般在一定區間內,為了更好的能顯示出幅度的變化,那麼用折線圖來展示無疑是最符合效果的,當然了,網上也有很多的第

Android定義控制元件實現滑動選擇開關

前言:今天我們仿照著Google給我們提供的Switch控制元件來進行一次模仿,自己動手打造一個可以換滑動圖片以及背景的圖片。 -----------------分割線--------------- 先看一下google提供的Switc控制元件: 其實用法很簡單就當普通的

Android 定義控制元件繼承view

一.自定義控制元件的型別:            1.繼承view(自繪檢視:view中的內容是我們自己繪製出來的,需要重寫onDraw方法)            2.繼承已有原生控制元件            3.自定義組合控制元件(將系統原生的控制元件組合到一起) 本

android定義控制元件圓形進度條(帶動畫)

首先貼上圖片: 額,感覺還行吧,就是進度條的顏色醜了點,不過咱是程式設計師,不是美工,配色這種問題當然不在考慮範圍之內了 下面說重點,如何來寫一個這樣的自定義控制元件。 首先,需要有一個灰色的底圖,來作為未填充時的進度條; 然後,根據傳入的當前進度值,繪製填充時的進度圓

安卓定義控制元件定義ViewGroup實現透明背景的ViewPager效果

HelloWorld! 作為一名屌絲程式設計師,在部落格園寫第一篇技術部落格內心是無比激動滴,其實作為一名忙成狗的Android開發人員,一直覺得自己永遠都不會有時間去寫部落格, 因為我TM連找女朋友的時間都沒用== 言歸正傳,今天自定義控制元件系列要實現的效果是自定義Vi