Android實(shí)現(xiàn)音頻條形圖效果
本文實(shí)例為大家分享了Android實(shí)現(xiàn)音頻條形圖效果的具體代碼,供大家參考,具體內(nèi)容如下
效果圖:

通過自定義View和屬性動(dòng)畫實(shí)現(xiàn)此效果
public class BarChartView extends LinearLayout implements Runnable {
? ? private ViewWrapper[] mViewWrapper;
? ? private int barchartCount = 1;
? ? private int barchartWidth = 20;
? ? private int barchartHeight = 0;
? ? private int barcharMarginLeft = 5;
? ? private int barchartDuration = 500;
? ? private int barcharBackColor;
? ? private boolean startAnimtor = false;
? ? @DrawableRes
? ? private int myShape;
? ? public BarChartView(Context context) {
? ? ? ? this(context, null);
? ? }
? ? public BarChartView(Context context, @Nullable AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }
? ? public BarChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
? ? ? ? super(context, attrs, defStyleAttr);
? ? ? ? init(context, attrs);
? ? ? ? addBarView();
? ? }
? ? /**
? ? ?* 初始化配置
? ? ?*
? ? ?* @param context
? ? ?* @param attrs
? ? ?*/
? ? private void init(Context context, @Nullable AttributeSet attrs) {
? ? ? ? setOrientation(LinearLayout.HORIZONTAL);
? ? ? ? setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
? ? ? ? TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BarChartView);
? ? ? ? barchartCount = typedArray.getInt(R.styleable.BarChartView_barchartCount, 0);
? ? ? ? barchartWidth = typedArray.getDimensionPixelSize(R.styleable.BarChartView_barchartWidth, 0);
? ? ? ? barchartHeight = typedArray.getDimensionPixelSize(R.styleable.BarChartView_barchartHeight, 0);
? ? ? ? barcharMarginLeft = typedArray.getDimensionPixelSize(R.styleable.BarChartView_barcharMarginLeft, 0);
? ? ? ? barchartDuration = typedArray.getInt(R.styleable.BarChartView_barchartDuration, 500);
? ? ? ? myShape = typedArray.getResourceId(R.styleable.BarChartView_barchartShape, 0);
? ? ? ? barcharBackColor = typedArray.getColor(R.styleable.BarChartView_barcharBackColor, Color.RED);
? ? ? ? typedArray.recycle();
? ? }
? ? /**
? ? ?* add View
? ? ?*/
? ? private void addBarView() {
? ? ? ? if (barchartCount <= 0) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? mViewWrapper = new ViewWrapper[barchartCount];
? ? ? ? ImageView childView;
? ? ? ? LinearLayout.LayoutParams layoutParams;
? ? ? ? ViewWrapper viewWrapper;
? ? ? ? for (int i = 0; i < barchartCount; i++) {
? ? ? ? ? ? childView = new ImageView(getContext());
? ? ? ? ? ? if (myShape != 0) {
? ? ? ? ? ? ? ? childView.setBackgroundResource(myShape);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? childView.setBackgroundColor(barcharBackColor);
? ? ? ? ? ? }
? ? ? ? ? ? layoutParams = new LayoutParams(barchartWidth, 100);
? ? ? ? ? ? layoutParams.setMargins(barcharMarginLeft, 0, 0, 0);
? ? ? ? ? ? childView.setLayoutParams(layoutParams);
? ? ? ? ? ? addView(childView);
? ? ? ? ? ? viewWrapper = new ViewWrapper(childView);
? ? ? ? ? ? mViewWrapper[i] = viewWrapper;
? ? ? ? }
? ? }
? ? /**
? ? ?* 開始動(dòng)畫
? ? ?*/
? ? public void start() {
? ? ? ? if (mViewWrapper == null || mViewWrapper.length <= 0) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? startAnimtor = true;
? ? ? ? Random a = new Random();
? ? ? ? for (int i = 0; i < mViewWrapper.length; i++) {
? ? ? ? ? ? startAnimator(mViewWrapper[i], a.nextInt(barchartHeight));
? ? ? ? }
? ? ? ? removeCallbacks(this);
? ? ? ? postDelayed(this, barchartDuration);
? ? }
? ? /**
? ? ?* 停止動(dòng)畫
? ? ?*/
? ? public void stop() {
? ? ? ? startAnimtor = false;
? ? ? ? for (int i = 0; i < mViewWrapper.length; i++) {
? ? ? ? ? ? startAnimator(mViewWrapper[i], 1);
? ? ? ? }
? ? }
? ? private void startAnimator(ViewWrapper viewWrapper, int height) {
? ? ? ? viewWrapper.mTarget.clearAnimation();
? ? ? ? ObjectAnimator.ofInt(viewWrapper, "height", height).setDuration(barchartDuration).start();
? ? }
? ? @Override
? ? public void run() {
? ? ? ? if (startAnimtor) {
? ? ? ? ? ? start();
? ? ? ? }
? ? }
? ??
? ? private static class ViewWrapper {
? ? ? ? public View mTarget;
? ? ? ? public ViewWrapper(View target) {
? ? ? ? ? ? mTarget = target;
? ? ? ? }
? ? ? ? public int getWidth() {
? ? ? ? ? ? return mTarget.getLayoutParams().width;
? ? ? ? }
? ? ? ? public void setWidth(int width) {
? ? ? ? ? ? mTarget.getLayoutParams().width = width;
? ? ? ? ? ? mTarget.requestLayout();
? ? ? ? }
? ? ? ? public int getHeight() {
? ? ? ? ? ? return mTarget.getLayoutParams().height;
? ? ? ? }
? ? ? ? public void setHeight(int height) {
? ? ? ? ? ? mTarget.getLayoutParams().height = height;
? ? ? ? ? ? mTarget.requestLayout();
? ? ? ? }
? ? }
}自定義屬性
<declare-styleable name="BarChartView"> ? ? ? ? <attr name="barchartCount" format="integer" /> ? ? ? ? <attr name="barchartDuration" format="integer" /> ? ? ? ? <attr name="barchartShape" format="reference" /> ? ? ? ? <attr name="barchartHeight" format="dimension" /> ? ? ? ? <attr name="barchartWidth" format="dimension" /> ? ? ? ? <attr name="barcharMarginLeft" format="dimension" /> ? ? ? ? <attr name="barcharBackColor" format="color" /> </declare-styleable>
布局文件:
<?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-auto" ? ? xmlns:tools="http://schemas.android.com/tools" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent" ? ? android:orientation="vertical" ? ? tools:context="com.tlkg.testdemo.valueanimatordemo.MainActivity"> ? ? <LinearLayout ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="0dp" ? ? ? ? android:layout_weight="1" ? ? ? ? android:orientation="horizontal"> ? ? ? ? <com.tlkg.testdemo.valueanimatordemo.BarChartView ? ? ? ? ? ? android:id="@+id/myRealMapView" ? ? ? ? ? ? android:layout_width="0dp" ? ? ? ? ? ? android:layout_height="match_parent" ? ? ? ? ? ? android:layout_weight="1" ? ? ? ? ? ? app:barcharMarginLeft="3dp" ? ? ? ? ? ? app:barchartCount="10" ? ? ? ? ? ? app:barchartDuration="500" ? ? ? ? ? ? app:barchartHeight="100dp" ? ? ? ? ? ? app:barchartWidth="10dp" /> ? ? ? ? <com.tlkg.testdemo.valueanimatordemo.BarChartView ? ? ? ? ? ? android:id="@+id/myRealMapView1" ? ? ? ? ? ? android:layout_width="0dp" ? ? ? ? ? ? android:layout_height="match_parent" ? ? ? ? ? ? android:layout_weight="1" ? ? ? ? ? ? android:background="#ff000000" ? ? ? ? ? ? app:barcharBackColor="#ffffffff" ? ? ? ? ? ? app:barcharMarginLeft="3dp" ? ? ? ? ? ? app:barchartCount="10" ? ? ? ? ? ? app:barchartDuration="500" ? ? ? ? ? ? app:barchartHeight="70dp" ? ? ? ? ? ? app:barchartWidth="5dp" /> ? ? </LinearLayout> ? ? <LinearLayout ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="0dp" ? ? ? ? android:layout_weight="1" ? ? ? ? android:orientation="horizontal"> ? ? ? ? <com.tlkg.testdemo.valueanimatordemo.BarChartView ? ? ? ? ? ? android:id="@+id/myRealMapView2" ? ? ? ? ? ? android:layout_width="0dp" ? ? ? ? ? ? android:layout_height="match_parent" ? ? ? ? ? ? android:layout_weight="1" ? ? ? ? ? ? app:barcharMarginLeft="1dp" ? ? ? ? ? ? app:barchartCount="50" ? ? ? ? ? ? app:barchartDuration="300" ? ? ? ? ? ? app:barchartHeight="40dp" ? ? ? ? ? ? app:barcharBackColor="#ff0000ff" ? ? ? ? ? ? app:barchartWidth="2dp" /> ? ? ? ? <com.tlkg.testdemo.valueanimatordemo.BarChartView ? ? ? ? ? ? android:id="@+id/myRealMapView3" ? ? ? ? ? ? android:layout_width="0dp" ? ? ? ? ? ? android:layout_height="match_parent" ? ? ? ? ? ? android:layout_weight="1" ? ? ? ? ? ? app:barcharMarginLeft="3dp" ? ? ? ? ? ? app:barchartCount="8" ? ? ? ? ? ? app:barchartDuration="200" ? ? ? ? ? ? app:barchartHeight="90dp" ? ? ? ? ? ? app:barchartShape="@drawable/mshape" ? ? ? ? ? ? app:barchartWidth="10dp" /> ? ? </LinearLayout> ? ? <LinearLayout ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:gravity="center" ? ? ? ? android:orientation="horizontal"> ? ? ? ? <Button ? ? ? ? ? ? android:id="@+id/start" ? ? ? ? ? ? android:layout_width="wrap_content" ? ? ? ? ? ? android:layout_height="wrap_content" ? ? ? ? ? ? android:text="start" /> ? ? ? ? <Button ? ? ? ? ? ? android:id="@+id/stop" ? ? ? ? ? ? android:layout_width="wrap_content" ? ? ? ? ? ? android:layout_height="wrap_content" ? ? ? ? ? ? android:text="stop" /> ? ? </LinearLayout> </LinearLayout>
MainActivity代碼:
public class MainActivity extends AppCompatActivity {
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_main);
? ? ? ? final BarChartView realMapView = (BarChartView) findViewById(R.id.myRealMapView);
? ? ? ? final BarChartView realMapView1 = (BarChartView) findViewById(R.id.myRealMapView1);
? ? ? ? final BarChartView realMapView2 = (BarChartView) findViewById(R.id.myRealMapView2);
? ? ? ? final BarChartView realMapView3 = (BarChartView) findViewById(R.id.myRealMapView3);
? ? ? ? findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View v) {
? ? ? ? ? ? ? ? realMapView.start();
? ? ? ? ? ? ? ? realMapView1.start();
? ? ? ? ? ? ? ? realMapView2.start();
? ? ? ? ? ? ? ? realMapView3.start();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View v) {
? ? ? ? ? ? ? ? realMapView.stop();
? ? ? ? ? ? ? ? realMapView1.stop();
? ? ? ? ? ? ? ? realMapView2.stop();
? ? ? ? ? ? ? ? realMapView3.stop();
? ? ? ? ? ? }
? ? ? ? });
? ? }
}實(shí)現(xiàn)原理,BarChartView繼承線性布局,設(shè)置水平,內(nèi)容底部居中,根據(jù)初始化后的barchartCount屬性添加childView,調(diào)用方法start開始屬性動(dòng)畫。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義View實(shí)現(xiàn)簡單文字描邊功能
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)簡單文字描邊功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
Android如何使用ViewPager2實(shí)現(xiàn)頁面滑動(dòng)切換效果
這篇文章主要給大家介紹了關(guān)于Android如何使用ViewPager2實(shí)現(xiàn)頁面滑動(dòng)切換效果的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02
Android實(shí)戰(zhàn)打飛機(jī)游戲之實(shí)現(xiàn)主角以及主角相關(guān)元素(3)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)戰(zhàn)打飛機(jī)游戲之實(shí)現(xiàn)主角以及主角相關(guān)元素,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
Android下通過httpClient發(fā)送GET和POST請(qǐng)求的實(shí)例代碼
這篇文章介紹了Android下通過httpClient發(fā)送GET和POST請(qǐng)求的實(shí)例代碼,有需要的朋友可以參考一下2013-08-08
Android超實(shí)用的Toast提示框優(yōu)化分享
Toast是Android中用來顯示顯示信息的一種機(jī)制,和Dialog不一樣的是,Toast是沒有焦點(diǎn)的,而且Toast顯示的時(shí)間有限,過一定的時(shí)間就會(huì)自動(dòng)消失。那么這篇文章跟大家分享下Android中Toast的優(yōu)化,對(duì)大家日常開發(fā)還是很實(shí)用,下面來一起看看吧。2016-09-09
Android可自定義神奇動(dòng)效的卡片切換視圖實(shí)例
今天小編就為大家分享一篇關(guān)于Android可自定義神奇動(dòng)效的卡片切換視圖實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02
Android?使用flow實(shí)現(xiàn)倒計(jì)時(shí)的方式
這篇文章主要介紹了Android?使用flow實(shí)現(xiàn)倒計(jì)時(shí)的方式,借助Flow這個(gè)工具,更加優(yōu)雅地實(shí)現(xiàn)這個(gè)需求功能,文末給大家整理了Android?實(shí)現(xiàn)倒計(jì)時(shí)的幾種方式,需要的朋友可以參考下2022-04-04
Kotlin Service實(shí)現(xiàn)消息推送通知過程
這幾天分析了一下的啟動(dòng)過程,于是乎,今天寫一下Service使用; 給我的感覺是它并不復(fù)雜,千萬不要被一坨一坨的代碼嚇住了,雖然彎彎繞繞不少,重載函數(shù)一個(gè)接著一個(gè),就向走迷宮一樣,但只要抓住主線閱讀,很快就能找到出口2022-12-12

