您的位置:首页 > 其它

一个可以实时显示进度的自定义view,类似于listview中音乐播放背景变化的效果

2016-01-17 18:50 585 查看
package progresslayoutdemo.wjj.com.progresslayoutdemo;

import android.annotation.TargetApi;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.drawable.Animatable;

import android.os.Build;

import android.os.Handler;

import android.util.AttributeSet;

import android.view.View;

public class ProgressLayout extends View implements Animatable {

  private static final int COLOR_EMPTY_DEFAULT = 0x00000000;

  private static final int COLOR_LOADED_DEFAULT = 0x11FFFFFF;

  private static final int PROGRESS_SECOND_MS = 1000;

  private static Paint paintProgressLoaded;

  private static Paint paintProgressEmpty;

  private boolean isPlaying = false;

  private boolean isAutoProgress;

  private int mHeight;

  private int mWidth;

  private int maxProgress;

  private int currentProgress = 0;

  private Handler handlerProgress;

  private ProgressLayoutListener progressLayoutListener;

  public ProgressLayout(Context context) {

    this(context, null);

  }

  public ProgressLayout(Context context, AttributeSet attrs) {

    this(context, attrs, 0);

  }

  public ProgressLayout(Context context, AttributeSet attrs, int defStyleAttr) {

    super(context, attrs, defStyleAttr);

    init(context, attrs);

  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)

  public ProgressLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {

    super(context, attrs, defStyleAttr, defStyleRes);

    init(context, attrs);

  }

  @Override public boolean isRunning() {

    return isPlaying;

  }

  @Override public void start() {

    if (isAutoProgress) {

      isPlaying = true;

      handlerProgress.removeCallbacksAndMessages(null);

      handlerProgress.postDelayed(mRunnableProgress, 0);

    }

  }

  @Override public void stop() {

    isPlaying = false;

    handlerProgress.removeCallbacks(mRunnableProgress);

    postInvalidate();

  }

  @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    mWidth = MeasureSpec.getSize(widthMeasureSpec);

    mHeight = MeasureSpec.getSize(heightMeasureSpec);

  }

  @Override protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);

    canvas.drawRect(0, 0, mWidth, mHeight, paintProgressEmpty);

    canvas.drawRect(0, 0, calculatePositionIndex(currentProgress), mHeight, paintProgressLoaded);

  }

  private void init(Context context, AttributeSet attrs) {

    setWillNotDraw(false);

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.progressLayout);

    isAutoProgress = a.getBoolean(R.styleable.progressLayout_autoProgress, true);

    maxProgress = a.getInt(R.styleable.progressLayout_maxProgress, 0);

    maxProgress = maxProgress * 10;

    int loadedColor = a.getColor(R.styleable.progressLayout_loadedColor, COLOR_LOADED_DEFAULT);

    int emptyColor = a.getColor(R.styleable.progressLayout_emptyColor, COLOR_EMPTY_DEFAULT);

    a.recycle();

    paintProgressEmpty = new Paint();

    paintProgressEmpty.setColor(emptyColor);

    paintProgressEmpty.setStyle(Paint.Style.FILL);

    paintProgressEmpty.setAntiAlias(true);

    paintProgressLoaded = new Paint();

    paintProgressLoaded.setColor(loadedColor);

    paintProgressLoaded.setStyle(Paint.Style.FILL);

    paintProgressLoaded.setAntiAlias(true);

    handlerProgress = new Handler();

  }

  private int calculatePositionIndex(int currentProgress) {

    return (currentProgress * mWidth) / maxProgress;

  }

  public boolean isPlaying() {

    return isPlaying;

  }

  public void cancel() {

    isPlaying = false;

    currentProgress = 0;

    handlerProgress.removeCallbacks(mRunnableProgress);

    postInvalidate();

  }

  public void setCurrentProgress(int currentProgress) {

    this.currentProgress = currentProgress * 10;

    postInvalidate();

  }

  public void setMaxProgress(int maxProgress) {

    this.maxProgress = maxProgress * 10;

    postInvalidate();

  }

  public void setAutoProgress(boolean isAutoProgress) {

    this.isAutoProgress = isAutoProgress;

  }

  public void setProgressLayoutListener(ProgressLayoutListener progressLayoutListener) {

    this.progressLayoutListener = progressLayoutListener;

  }

  private final Runnable mRunnableProgress = new Runnable() {

    @Override public void run() {

      if (isPlaying) {

        if (currentProgress == maxProgress) {

          if (progressLayoutListener != null) {

            progressLayoutListener.onProgressCompleted();

          }

          currentProgress = 0;

          setCurrentProgress(currentProgress);

          stop();

        } else {

          postInvalidate();

          currentProgress += 1;

          if (progressLayoutListener != null) {

            progressLayoutListener.onProgressChanged(currentProgress / 10);

          }

          handlerProgress.postDelayed(mRunnableProgress, PROGRESS_SECOND_MS / 10);

        }

      }

    }

  };

}

package progresslayoutdemo.wjj.com.progresslayoutdemo;

import android.os.Handler;

import android.support.v7.widget.RecyclerView;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.TextView;

import java.util.List;

import butterknife.Bind;

import butterknife.ButterKnife;

public class RecylerListAdapter extends RecyclerView.Adapter<RecylerListAdapter.ViewHolder> {

  /**

   * 数据源集合

   */

  private List<Track> trackList;

  /**

   * 当前播放的对象。

   */

  private Track currentTrack;

  /**

   * 持续时间

   */

  private int currentDuration = 0;

  /**

   * 是否正在播放

   */

  private boolean isPlaying = false;

  private static final int SECOND_MS = 1000;

  /**

   * recyclerview中调用的Handle

   */

  private Handler mHandler = new Handler();

  /**

   * 计算秒数

   *

   */

  private final Runnable mRunnable = new Runnable() {

    @Override public void run() {

      currentDuration += 1;

      mHandler.postDelayed(mRunnable, SECOND_MS);

    }

  };

  /**

   * 传参

   */

  public void setTrackList(List<Track> trackList) {

    this.trackList = trackList;

    notifyDataSetChanged();

  }

  /**

   * 创建holder

   */

  @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

    View view =

        LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_item, viewGroup, false);

    ViewHolder viewHolder = new ViewHolder(view);

    return viewHolder;

  }

  /**

   * 绑定对象

   */

  @Override public void onBindViewHolder(final ViewHolder viewHolder, final int i) {

    final Track track = trackList.get(i);

    viewHolder.textViewDuration.setText(calculateSongDuration(track.getDurationInSec()));

    viewHolder.textViewSong.setText(track.getSongName());

    viewHolder.textViewSinger.setText(track.getSingerName());

    viewHolder.imageViewAction.setBackgroundResource(R.drawable.play);

    viewHolder.progressLayout.setMaxProgress(track.getDurationInSec());

    if (currentTrack != null && currentTrack == track) {

      viewHolder.imageViewAction.setBackgroundResource(

          isPlaying ? R.drawable.pause : R.drawable.play);

      viewHolder.progressLayout.setCurrentProgress(currentDuration);

      if (isPlaying) viewHolder.progressLayout.start();

    } else {

      viewHolder.progressLayout.cancel();

    }

    viewHolder.imageViewAction.setOnClickListener(new View.OnClickListener() {

      @Override public void onClick(View v) {

        if (track != currentTrack) {

          currentTrack = track;

          mHandler.removeCallbacks(mRunnable);

          currentDuration = 0;

        }

        if (!viewHolder.progressLayout.isPlaying()) {

          isPlaying = true;

          viewHolder.progressLayout.start();

          mHandler.postDelayed(mRunnable, 0);

          viewHolder.imageViewAction.setBackgroundResource(R.drawable.pause);

          notifyDataSetChanged();

        } else {

          isPlaying = false;

          viewHolder.progressLayout.stop();

          mHandler.removeCallbacks(mRunnable);

          viewHolder.imageViewAction.setBackgroundResource(R.drawable.play);

          notifyDataSetChanged();

        }

      }

    });

    /*

    * 播放按钮的监听事件

    * */

    viewHolder.progressLayout.setProgressLayoutListener(new ProgressLayoutListener() {

      @Override public void onProgressCompleted() {

        viewHolder.imageViewAction.setBackgroundResource(R.drawable.play);

      }

      @Override public void onProgressChanged(int seconds) {

        viewHolder.textViewDuration.setText(calculateSongDuration(seconds));

      }

    });

  }

  /**

   * List大小

   */

  @Override public int getItemCount() {

    return trackList.size();

  }

  /**

   * 换成分钟

   */

  private String calculateSongDuration(int seconds) {

    return new StringBuilder(String.valueOf(seconds / 60))

        .append(":")

        .append(String.valueOf(seconds % 60))

        .toString();

  }

  /**

   * ViewHolder对象

   */

  public static class ViewHolder extends RecyclerView.ViewHolder {

    @Bind(R.id.imageviewAction) ImageView imageViewAction;

    @Bind(R.id.progressLayout) ProgressLayout progressLayout;

    @Bind(R.id.textviewSong) TextView textViewSong;

    @Bind(R.id.textviewSinger) TextView textViewSinger;

    @Bind(R.id.textviewDuration) TextView textViewDuration;

    public ViewHolder(View itemView) {

      super(itemView);

      ButterKnife.bind(this, itemView);

    }

  }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: