안 드 로 이 드 모방 매일 듣 기 좋 은 노래 자동 스크롤 view
11341 단어 Android날마다 듣 기 좋다자동 스크롤view
본문
생각 1:미 끄 러 지 는 거 리 를 얻 고 얼마나 미 끄 러 졌 는 지 계산 한 다음 에 데 이 터 를 업데이트 합 니 다.실현 해 보 니 효과 가 별로 없 는 것 같다.
생각 2:우 리 는 그 가 구 르 는 것 이 한 줄 한 줄 구 르 는 것 임 을 알 수 있다.다만 구 르 는 속도 에 따라 구 르 는 줄 의 속 도 를 결정 할 뿐이다.그렇다면 스크롤 만 하면 일정 시간 한 줄 의 스크롤 을 한 다음 스크롤 속도 에 따라 업데이트 간격 을 결정 합 니 다.
응,어떻게 실현 할 지 생각 했 으 니 지금 코드 를 써 라.
먼저 클래스 를 써 서 TextView 를 계승 합 니 다.
VerticalScrollTextView.class
public class VerticalScrollTextView extends TextView implements Runnable{
//
private Paint mContentPaint;
//
private Paint mLinePaint;
//
private Paint mRectPaint;
//
private List<Sentence> mDataList;
//
private int index = 0 ;
// view
private float mX;
// view
private float mY;
// view
private float middleY;
//
private final static int DY = 80 ;
//
private int mTextSize = 35;
//
private int mBigTextSize = 45;
//
private boolean isTouch = false ;
// view y
private float mLastY;
//
private boolean isMoving;
//
private long lastMoveTime;
//
private VelocityTracker mVelocityTracker;
//
private int mMaximumVelocity;
//
private boolean isEmpty;
public VerticalScrollTextView(Context context) {
this(context,null);
}
public VerticalScrollTextView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public VerticalScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//
mMaximumVelocity = ViewConfiguration.get(context)
.getScaledMaximumFlingVelocity();
init();
}
private void init(){
setFocusable(true);
setClickable(true);
//
if(mDataList==null){
mDataList = new ArrayList<>();
Sentence sentence = new Sentence(0," ",0);
mDataList.add(sentence);
isEmpty = true ;
}
//
mContentPaint = new Paint();
mContentPaint.setTextSize(mTextSize);
mContentPaint.setAntiAlias(true);
mContentPaint.setColor(Color.parseColor("#e5e2e2"));
// serif
mContentPaint.setTypeface(Typeface.SERIF);
//
mContentPaint.setTextAlign(Paint.Align.CENTER);
//
mLinePaint = new Paint();
mLinePaint.setAntiAlias(true);
mLinePaint.setStrokeWidth(1);
mLinePaint.setColor(Color.WHITE);
//
mRectPaint = new Paint();
mLinePaint.setAntiAlias(true);
mRectPaint.setColor(Color.parseColor("#66666666"));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// -1, ,
if (index == -1)
return;
Sentence sentence = mDataList.get(index);
// , ,
mContentPaint.setColor(Color.WHITE);
mContentPaint.setTextSize(mBigTextSize);
canvas.drawText(sentence.getName(), mX/2, middleY, mContentPaint);
// ,
if(!isEmpty&&isTouch){
//
float baseLine = middleY-Math.abs(mContentPaint.ascent());
//
canvas.drawRect(10.0f,baseLine-70,150.0f,baseLine,mRectPaint);
//
canvas.drawLine(10.0f,baseLine,mX-10,baseLine,mLinePaint);
//
mContentPaint.setTextSize(mTextSize);
//
canvas.drawText(String.valueOf(index),85,baseLine-35,mContentPaint);
}
// isEmpty
isEmpty = false ;
//
mContentPaint.setColor(Color.parseColor("#e5e2e2"));
mContentPaint.setTextSize(mTextSize);
// ,
float tempY = middleY;
//
for (int i = index - 1; i >= 0; i--) {
tempY = tempY - DY;
if (tempY < 0) {
break;
}
Sentence preSentence = mDataList.get(i);
canvas.drawText(preSentence.getName(), mX/2, tempY, mContentPaint);
}
tempY = middleY;
//
for (int i = index + 1; i < mDataList.size(); i++) {
tempY = tempY + DY;
if (tempY > mY) {
break;
}
Sentence nexeSentence = mDataList.get(i);
canvas.drawText(nexeSentence.getName(), mX/2, tempY, mContentPaint);
}
// isMoving,
isMoving = false ;
}
protected void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh);
// view
mX = w;
mY = h;
middleY = h * 0.5f;
}
public long updateIndex(int index) {
if (index == -1)
return -1;
this.index=index;
return index;
}
public List<Sentence> getDataList() {
return mDataList;
}
public void setDataList(List<Sentence> mDataList){
this.mDataList = mDataList ;
}
public void updateUI(){
new Thread(this).start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
isTouch =true;
mLastY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
//
initVelocityTrackerIfNotExists();
mVelocityTracker.addMovement(event);
mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
// 。 100
float velocity = mVelocityTracker.getYVelocity()==0?100:mVelocityTracker.getYVelocity();
long currentTime = System.currentTimeMillis();
//
if(!isMoving&¤tTime-lastMoveTime>20000/Math.abs(velocity)){
isMoving = true ;
lastMoveTime = System.currentTimeMillis();
float currentY = event.getY();
float mMoveY = currentY - mLastY;
// -1 +1
int newIndex = mMoveY>0?index - 1:index+1;
//
newIndex=newIndex<0?mDataList.size()-1:newIndex>=mDataList.size()?0:newIndex;
updateIndex(newIndex);
invalidate();
mLastY = currentY;
}
break;
case MotionEvent.ACTION_UP:
isTouch = false ;
recycleVelocityTracker();
break;
}
return super.onTouchEvent(event);
}
@Override
public void run() {
//
long time = 1000;
//
int i=0;
while (true) {
//
if(!isTouch){
//
long sleeptime = updateIndex(i);
// handle ui
mHandler.post(mUpdateResults);
if (sleeptime == -1)
return;
try {
Thread.sleep(time);
i++;
//
if(i==getDataList().size())
i=0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler mHandler = new Handler();
Runnable mUpdateResults = new Runnable() {
public void run() {
invalidate();
}
};
//
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}
//
private void recycleVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
}
사용자 정의 view 는 기본적으로 이 렇 습 니 다.우 리 는 정의 할 속성 을 attrs 에 쓸 수 있 습 니 다.여 기 는 쓰기 가 귀 찮 습 니 다.대략적인 사고방식 은 먼저 지 정 된 index 줄 의 가 사 를 그린 다음 에 index 위 줄 의 가 사 를 그린 다음 에 index 아래 줄 의 가 사 를 그 리 는 것 이다.그리고 handle 을 통 해 일정 시간 간격 으로 가사 줄 수 를 새로 고 칠 수 있 도록 스 레 드 를 새로 만 듭 니 다.그리고 onTouchEvent 에서 터치 스크롤 줄 수 를 처리 하고 현재 스크롤 속 도 를 가 져 와 업데이트 시간 간격 을 결정 합 니 다.터치 스크롤 리 셋 의 속 도 를 실현 합 니 다.기본적으로 이렇다.다른 것 은 주석 을 보십시오.데이터 테스트 를 초기 화 하 는 Activity:
VerticalScrollTextActivity.class
public class VerticalScrollTextActivity extends Activity {
VerticalScrollTextView mSampleView;
String[] str = {" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSampleView = (VerticalScrollTextView) findViewById(R.id.sampleView1);
List lst=new ArrayList<>();
for(int i=0;i<str.length;i++){
Sentence sen=new Sentence(i,str[i],i+1202034);
lst.add(i, sen);
}
mSampleView.setDataList(lst);
mSampleView.updateUI();
}
}
가사 데 이 터 를 모 의 한 다음 setDataList 에서 updateUI()를 호출 하면 됩 니 다.마지막 으로 레이아웃 파일 보기
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.goach.lib.VerticalScrollTextView
android:id="@+id/sampleView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"
/>
</RelativeLayout>
테스트 를 해 보면 우 리 는 효 과 를 볼 수 있다.원본 다운로드:안 드 로 이 드 모방 매일 듣 기 좋 은 노래 자동 스크롤
이상 은 본 고의 모든 내용 입 니 다.여러분 이 안 드 로 이 드 소프트웨어 프로 그래 밍 을 배 우 는 데 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.