Realization of lyrics display function by android player

  • 2021-10-16 05:03:05
  • OfStack

Although there are a lot of online android players, it feels that the lyrics display function provided is rigid, either the search conditions are dead, or the lyrics format inside sdcard needs to be unified, and it should provide similar folder browsing functions. ^ _ ^, but before that, get the realistic interface of lyrics:

The lyrics interface of the player realizes the following functions

Scroll from bottom to top according to the playing progress of songs; Provide the function of dragging up and down to adjust the progress of songs; Highlight the lyrics segment of the current progress and ensure that the lyrics segment is in the center of the layout

Not much to say directly paste the code, first open a thread to send a string of characters to view every 1 period of time

Java code


import android.os.Bundle; 
import android.os.Handler; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
 
public class TextAlign extends GraphicsActivity implements OnClickListener { 
 
  private SampleView mView; 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    // Animation in = AnimationUtils.loadAnimation(this, R.anim.push_up_in); 
 
    // mView.setAnimation(in); 
    setContentView(R.layout.main); 
    mView =(SampleView) findViewById(R.id.text01); 
 
    Button bt = (Button) findViewById(R.id.Button01); 
    bt.setOnClickListener(this); 
     
    new Thread(new UIUpdateThread()).start(); 
 
  } 
 
  class UIUpdateThread implements Runnable { 
    long time = 40000; 
 
    long sleeptime = 100; 
    public void run() { 
      try { 
        while (time < 200000) { 
          Thread.sleep(sleeptime); 
          mView.updateIndex(time);//.index = mLyric.getNowSentenceIndex(time); 
//         Log.v("UIThread", mView.index + ":" + time); 
          time += sleeptime; 
          mHandler.post(mUpdateResults); 
        } 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
    } 
  } 
  Handler mHandler = new Handler(); 
  Runnable mUpdateResults = new Runnable() { 
    public void run() { 
      mView.invalidate(); //  Update view  
    } 
  }; 
 
  @Override 
  public void onClick(View v) { 
    mView.mTouchHistoryY -=30; 
    mHandler.post(mUpdateResults); 
  } 
} 

Here, the time is sent to SampleView, and this class processes this time to obtain a series of list (the list is dynamically generated), thus obtaining a series of strings incrementally according to the passage of time. This process simulates the display process of lyrics

The next SampleView inherits TextView and overloads the onDraw method. Note that only sample is given here. See YOYOPlayer for how the lyrics are generated. No code here

Java code


import java.io.File; 
import java.util.List; 
 
import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.graphics.Typeface; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.widget.TextView; 
import android.widget.Toast; 
 
import com.android.lyric.Lyric; 
import com.android.lyric.PlayListItem; 
import com.android.lyric.Sentence; 
 
public class SampleView extends TextView { 
    private Paint mPaint; 
    private float mX; 
    private static Lyric mLyric; 
 
    private Path mPath; 
    private Paint mPathPaint; 
    public String test = "test"; 
    public int index = 0; 
    private List<Sentence> list; 
 
    private float mTouchStartY; 
    private float mTouchCurrY; 
    public float mTouchHistoryY; 
 
    private int mY; 
    private long currentTime; 
    private long currentDunringTime; 
    private long sentenctTime; 
    private float middleY; 
    private String middleContent="Empty"; 
    private static final int DY = 30; 
 
    private static void makePath(Path p) { 
      p.moveTo(10, 0); 
      p.cubicTo(100, -50, 200, 50, 300, 0); 
    } 
 
 
    public SampleView(Context context) { 
      super(context); 
      init(); 
    } 
    public SampleView(Context context,AttributeSet attr) { 
      super(context,attr); 
      init(); 
    } 
    public SampleView(Context context,AttributeSet attr,int i) { 
      super(context,attr,i); 
      init(); 
    } 
 
    private void init() { 
      setFocusable(true); 
      PlayListItem pli = new PlayListItem("", "", 1000L, true); 
      mLyric = new Lyric(new File("/sdcard/M0005044007.lrc"), pli); 
 
      list = mLyric.list; 
      mPaint = new Paint(); 
      mPaint.setAntiAlias(true); 
      mPaint.setTextSize(20); 
      mPaint.setTypeface(Typeface.SERIF); 
 
 
      mPath = new Path(); 
      makePath(mPath); 
 
      mPathPaint = new Paint(); 
      mPathPaint.setAntiAlias(true); 
      mPathPaint.setColor(0x800000FF); 
      mPathPaint.setStyle(Paint.Style.STROKE); 
    } 
 
     
    @Override 
    protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
 
      canvas.drawColor(Color.WHITE); 
 
      Paint p = mPaint; 
      float x = mX; 
      float plus =currentDunringTime==0?index*30: index*30 +(((float)currentTime - (float)sentenctTime)/(float)currentDunringTime)*(float)30; 
      float y = mY- plus+mTouchCurrY - mTouchStartY+mTouchHistoryY; 
         
      canvas.translate(0,y); 
 
      for (int i = 0; i < index; i++) { 
        String text = list.get(i).getContent(); 
        if((y+i*30)<=middleY&&(y+i*30+30)>=middleY) 
          middleContent = text; 
        p.setTextAlign(Paint.Align.CENTER); 
        canvas.drawText(text, x, 0, p); 
        // mY- mY/lines*(index - i) 
        canvas.translate(0, DY); 
      } 
    } 
 
 
    @Override 
    protected void onSizeChanged(int w, int h, int ow, int oh) { 
      super.onSizeChanged(w, h, ow, oh); 
      mX = w * 0.5f; // remember the center of the screen 
      mY = h; 
      middleY = h*0.5f; 
    } 
 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
      float y = event.getY(); 
 
      switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
        mTouchHistoryY += mTouchCurrY - mTouchStartY; 
        mTouchStartY =mTouchCurrY= y; 
        invalidate(); 
        break; 
      case MotionEvent.ACTION_MOVE: 
        mTouchCurrY = y; 
        invalidate(); 
        break; 
      case MotionEvent.ACTION_UP: 
        Log.v("Lyric content", middleContent.length()+""); 
        CharSequence chars = new CharSequence(){ 
 
          @Override 
          public char charAt(int index) { 
            // TODO Auto-generated method stub 
            return middleContent.charAt(index); 
          } 
 
          @Override 
          public int length() { 
            // TODO Auto-generated method stub 
            return middleContent.length(); 
          } 
 
          @Override 
          public CharSequence subSequence(int start, int end) { 
            // TODO Auto-generated method stub 
            return middleContent.subSequence(start, end); 
          } 
          @Override 
          public String toString(){ 
            return middleContent; 
          } 
        }; 
        Toast toast = Toast.makeText(SampleView.this.getContext(),chars, 1000); 
        toast.show(); 
        invalidate(); 
        break; 
      } 
      return true; 
    } 
 
 
    public void updateIndex(long time) { 
      this.currentTime = time; 
      index = mLyric.getNowSentenceIndex(time); 
      Sentence sen = list.get(index); 
      currentDunringTime = sen.getDuring(); 
      sentenctTime = sen.getFromTime(); 
    } 
  } 


Related articles: