自定义列表数据自动循环向下滚动view(类似于通知通报消息)
Posted oooohuhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义列表数据自动循环向下滚动view(类似于通知通报消息)相关的知识,希望对你有一定的参考价值。
首先申明,这个自定义View不是本人写的,大神写的,本人仅限学习一级研究使用
直接上代码吧!后面我再解释一遍
1 package com.egojit.android.gcoa.views; 2 3 import android.animation.Animator; 4 import android.animation.TypeEvaluator; 5 import android.animation.ValueAnimator; 6 import android.content.Context; 7 import android.graphics.Canvas; 8 import android.graphics.Color; 9 import android.graphics.Paint; 10 import android.graphics.Point; 11 import android.os.Handler; 12 import android.os.Message; 13 import android.support.annotation.Nullable; 14 import android.util.AttributeSet; 15 import android.util.DisplayMetrics; 16 import android.view.View; 17 import android.view.WindowManager; 18 19 import com.asuka.android.asukaandroid.comm.utils.LogUtil; 20 import com.asuka.android.asukaandroid.view.EmptyView; 21 import com.egojit.android.gcoa.model.EmptyModel; 22 23 import java.util.List; 24 25 /** 26 * Created by Administrator on 2017/4/18 0018. 27 */ 28 29 public class CustomScorllView extends View { 30 private Context mContext; 31 private boolean hasStart=false; 32 private List<EmptyModel> sroucesList; 33 private double strHeight; 34 private Point startPoint; 35 private Point endPoint; 36 private boolean stop; 37 38 public void setSroucesList(List<EmptyModel> sroucesList) { 39 this.sroucesList = sroucesList; 40 type=getCurType(); 41 title=getCurTitle(); 42 invalidate(); 43 } 44 45 public CustomScorllView(Context context) { 46 super(context); 47 mContext=context; 48 } 49 50 public CustomScorllView(Context context, @Nullable AttributeSet attrs) { 51 super(context, attrs); 52 mContext=context; 53 } 54 55 public CustomScorllView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 56 super(context, attrs, defStyleAttr); 57 mContext=context; 58 } 59 60 public CustomScorllView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { 61 super(context, attrs, defStyleAttr, defStyleRes); 62 mContext=context; 63 } 64 65 private void startScorll() { 66 int tempY=y; 67 Message message=new Message(); 68 message.obj=tempY; 69 handler.sendMessage(message); 70 } 71 Handler handler=new Handler(){ 72 @Override 73 public void handleMessage(Message msg) { 74 super.handleMessage(msg); 75 int tempY= (int) msg.obj; 76 y=tempY; 77 78 if (tempY>-50){ 79 invalidate(); 80 tempY=tempY-1; 81 Message message=new Message(); 82 message.obj=tempY; 83 handler.sendMessage(message); 84 } 85 } 86 }; 87 int start,end; 88 public void start(){ 89 Point startPoint = new Point(start, 50); 90 Point endPoint = new Point(end, 50); 91 final ValueAnimator animator = ValueAnimator 92 .ofObject(new PointEvaluator(), startPoint, endPoint); 93 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 94 @Override 95 public void onAnimationUpdate(ValueAnimator animation) { 96 Point mPoint = ((Point) animation.getAnimatedValue()); 97 y=mPoint.x; 98 invalidate(); 99 } 100 }); 101 animator.addListener(new Animator.AnimatorListener() { 102 @Override 103 public void onAnimationStart(Animator animation) { 104 105 } 106 107 @Override 108 public void onAnimationEnd(Animator animation) { 109 //下一个显示 110 111 if ( start==baseline){ 112 start= (int) (-strHeight/2); 113 end=baseline; 114 EmptyModel model=sroucesList.get(0); 115 sroucesList.remove(0); 116 sroucesList.add(model); 117 type=getCurType(); 118 title=getCurTitle(); 119 start(); 120 }else { 121 start=baseline; 122 end= (int) (getMeasuredHeight()+strHeight/2); 123 new Handler().postDelayed(new Runnable() { 124 @Override 125 public void run() { 126 start(); 127 } 128 },4000); 129 } 130 131 132 } 133 134 @Override 135 public void onAnimationCancel(Animator animation) { 136 137 } 138 139 @Override 140 public void onAnimationRepeat(Animator animation) { 141 142 } 143 }); 144 animator.setDuration(3000); 145 animator.start(); 146 } 147 public void startAnimation() { 148 new Handler().postDelayed(new Runnable() { 149 @Override 150 public void run() { 151 hasStart=true; 152 type=getCurType(); 153 title=getCurTitle(); 154 start=baseline; 155 end= (int) (getMeasuredHeight()+strHeight/2); 156 startPoint = new Point(start, 50); 157 endPoint = new Point(end, 50); 158 start(); 159 } 160 },4000); 161 } 162 163 private String getCurTitle() { 164 return sroucesList.get(0).getVar1(); 165 } 166 167 private String getCurType() { 168 return sroucesList.get(0).getVar(); 169 } 170 171 private String getNextTitle() { 172 if (sroucesList.size()==1){ 173 return sroucesList.get(0).getVar1(); 174 }else { 175 return sroucesList.get(1).getVar1(); 176 } 177 178 } 179 180 private String getNextType() { 181 if (sroucesList.size()==1){ 182 return sroucesList.get(0).getVar(); 183 }else { 184 return sroucesList.get(1).getVar(); 185 } 186 } 187 188 int baseline=-999; 189 int y; 190 String type="哈哈哈"; 191 String title="个囊女女过过过过"; 192 @Override 193 protected void onDraw(Canvas canvas) { 194 super.onDraw(canvas); 195 196 Paint redPaint = new Paint(); 197 redPaint.setAntiAlias(true); 198 redPaint.setTextSize(gettextSize(45)); 199 redPaint.setColor(0xff50a3ef); 200 redPaint.setTextAlign(Paint.Align.LEFT); 201 202 Paint blckPaint = new Paint(); 203 blckPaint.setAntiAlias(true); 204 blckPaint.setTextSize(gettextSize(45)); 205 blckPaint.setColor(Color.BLACK); 206 blckPaint.setTextAlign(Paint.Align.LEFT); 207 208 Paint.FontMetricsInt fontMetrics = redPaint.getFontMetricsInt(); 209 String typeStr="[" + type + "]"; 210 //直接返回参数字符串所占用的宽度 211 float strWidth = redPaint.measureText(typeStr); 212 strHeight=getTxtHeight(redPaint)+15; 213 if (baseline==-999&&sroucesList!=null){ 214 baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top; 215 y=baseline; 216 } 217 // LogUtil.e("-----------------handler---------"+y); 218 canvas.drawText(typeStr, 30 , y , redPaint); 219 canvas.drawText(title, strWidth+60 , y , blckPaint); 220 221 } 222 public double getTxtHeight(Paint mPaint) { 223 Paint.FontMetrics fm = mPaint.getFontMetrics(); 224 return Math.ceil(fm.descent - fm.ascent); 225 } 226 public class PointEvaluator implements TypeEvaluator<Point> { 227 @Override 228 public Point evaluate(float fraction, Point startValue, Point endValue) { 229 // LogUtil.e("-----------------fraction---------"+fraction); 230 int resultX = (int) (fraction * (endValue.x-startValue.x)+startValue.x); 231 int resultY = (int) (fraction * startValue.y); 232 return new Point(resultX, resultY); 233 } 234 } 235 236 @Override 237 public void setOnClickListener(@Nullable OnClickListener l) { 238 super.setOnClickListener(l); 239 240 } 241 242 public List<EmptyModel> getSroucesList() { 243 return sroucesList; 244 } 245 246 public float gettextSize(float f){ 247 248 249 int screenWidth =getScreenWidth(mContext); 250 251 float ratioWidth = (float)screenWidth / 1080; 252 253 254 return Math.round(f * ratioWidth); 255 } 256 257 /** 258 * 获取屏幕宽度 259 * 260 * @return 261 */ 262 @SuppressWarnings("deprecation") 263 public int getScreenWidth(Context context) { 264 return ((WindowManager) context 265 .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay() 266 .getWidth(); 267 } 268 269 }
主界面布局为
1 <com.wangy.views.CustomScorllView 2 android:id="@+id/custom_scorllView" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent"></com.wany.views.CustomScorllView>
那么如何使用呢!
使用起来就很简单了
1 List<EmptyModel> alist=new ArrayList<>(); 2 for (int i=0;i<newsList.size();i++){ 3 JSONObject object=newsList.getJSONObject(i); 4 EmptyModel model=new EmptyModel(); 5 String fileType=object.getString("fileType"); 6 String title=object.getString("title"); 7 String id=object.getString("id"); 8 model.setVar(fileType); 9 model.setVar1(title); 10 model.setVar2(id); 11 alist.add(model); 12 } 13 if (alist.size()==0)return; 14 custom_scorllView.setSroucesList(alist); 15 custom_scorllView.startAnimation();
其中的newsList为列表数据,你可以从接口中取也可以put值,
EmptyModel为一个空model,他是用来直接设置接口参数形成一个model,这样使用起来比较方便
1 package com.egojit.android.gcoa.model; 2 3 4 /** 5 * Created by Administrator on 2016-06-14. 6 */ 7 public class EmptyModel extends Entity { 8 String var; 9 String var1; 10 String var2; 11 String var3; 12 String var4; 13 String var11; 14 String var12; 15 String var13; 16 String var14; 17 String var5; 18 String var15; 19 20 public String getVar5() { 21 return var5; 22 } 23 24 public void setVar5(String var5) { 25 this.var5 = var5; 26 } 27 28 public String getVar15() { 29 return var15; 30 } 31 32 public void setVar15(String var15) { 33 this.var15 = var15; 34 } 35 36 public String getVar11() { 37 return var11; 38 } 39 40 public void setVar11(String var11) { 41 this.var11 = var11; 42 } 43 44 public String getVar12() { 45 return var12; 46 } 47 48 public void setVar12(String var12) { 49 this.var12 = var12; 50 } 51 52 public String getVar13() { 53 return var13; 54 } 55 56 public void setVar13(String var13) { 57 this.var13 = var13; 58 } 59 60 public String getVar14() { 61 return var14; 62 } 63 64 public void setVar14(String var14) { 65 this.var14 = var14; 66 } 67 68 public String getVar1() { 69 return var1; 70 } 71 72 public void setVar1(String var1) { 73 this.var1 = var1; 74 } 75 76 public String getVar2() { 77 return var2; 78 } 79 80 public void setVar2(String var2) { 81 this.var2 = var2; 82 } 83 84 public String getVar3() { 85 return var3; 86 } 87 88 public void setVar3(String var3) { 89 this.var3 = var3; 90 } 91 92 public String getVar4() { 93 return var4; 94 } 95 96 public void setVar4(String var4) { 97 this.var4 = var4; 98 } 99 100 public String getVar() { 101 return var; 102 } 103 104 public void setVar(String var) { 105 this.var = var; 106 } 107 }
以上是关于自定义列表数据自动循环向下滚动view(类似于通知通报消息)的主要内容,如果未能解决你的问题,请参考以下文章
浅析在QtWidget中自定义Model(beginInsertRows()和endInsertRows()是空架子,类似于一种信号,用来通知底层)