float wechatIconX = ivWechat.getX();
int weChatIconWidth = ivWechat.getWidth();
float wechatIconCenterX = wechatIconX + weChatIconWidth / 2;
float popupWidthPX = getResources().getDimension(R.dimen.wechatPopUp_width);
ivWechatPopUp.setX(wechatIconCenterX - popupWidthPX / 2);
2017年3月10日 星期五
2016年10月1日 星期六
Specifica view raitio
https://plus.google.com/+AndroidDevelopers/posts/ZQS29a5yroK
use Percent Support Library
use Percent Support Library
2016年8月11日 星期四
make a view can scroll with the recycle view
44 make a view can scroll with the recycle view
use scroll view is ok
addView(View, LayoutParams) is not supported in AdapterView
28addView(View, LayoutParams) is not supported in AdapterView
need to use this
convertView = LayoutInflater.from(mcontext).inflate(R.layout.detaildialog_cell, parent,false);
2016年1月6日 星期三
View Groups(Layout),height,weight,gravity,Padding and Margin
View Groups
Frame layout:view in frame layout go to left up connear,one can cover another on,so always put on view inside
Linear layout:has layput weight
view Group also is a view,so,alyout is a view too
the tree:
↳
| |||
↳
| |||
↳
|
android.widget.LinearLayout
|
Height and Weight:
Gravity
Padding and Margin
Visibility
2015年10月14日 星期三
制作自定義的View4-使用XML修改 View
package pom.poly.com.trymakeviewbymyself.myView.v4; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import pom.poly.com.trymakeviewbymyself.R; import pom.poly.com.trymakeviewbymyself.myView.v3.BasicView; /** * Created by User on 14/10/2015. */ public class NumView extends BasicView { private Paint paint = new Paint(); private String showText = "I love you"; private int linenum=4; public NumView(Context context) { super(context); } public NumView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void drawsub(Canvas canvas) { int textSize=100; for (int i = 0; i < linenum; i++) { textSize = textSize + i*10; paint.setTextSize(textSize); canvas.drawText(showText, 0, textSize + textSize*i, paint); } } @Override protected void logic() { } }
How to no need change the code, use XML to change the number of line that show?
1.create a attrs.xml
in the xmal file
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="NumView"> <attr name="linenum" format="integer"></attr> </declare-styleable> </resources>
remark:<attr name="linenum" format="integer"></attr> 定義了 linenum e個 attribute 的鄰形是 int
2. use the XML
in the activity_mian.xml
add
xmlns:nv="http://schemas.android.com/apk/res-auto"
than you can use the linenum
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:nv="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <pom.poly.com.trymakeviewbymyself.myView.v4.NumView android:layout_width="fill_parent" android:layout_height="0dp" android:id="@+id/view" android:layout_weight="1" nv:linenum="6"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Button" android:id="@+id/bt1" /> </LinearLayout>
3.change the program that make the program can read the value type in the XML
public NumView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.NumView); linenum=ta.getInt(R.styleable.NumView_linenum,0); ta.recycle();//release the TypedArray }
remark:NumView define in the attrs.xml ,
must need release the TypedArray
制作自定義的View3-提取和封裝自定義View
上次已完成的自定義View
public class LogicView extends View { private Paint paint = new Paint(); private int rx = 0; private MyThread myThread = null; private String showString = "show me"; private RectF rectF = new RectF(0, 40, 600, 640); private float sweepAngle = 0; public LogicView(Context context) { super(context); } public LogicView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setTextSize(200); canvas.drawText(showString, rx, 300, paint); canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true? if (myThread == null) { myThread = new MyThread(); myThread.start(); } //invalidate(); //cal by ui thread //postInvalidate(); //canvas.drawText("hi",rx,300,paint); } class MyThread extends Thread { @Override public void run() { Random random = new Random(); super.run(); while (true) { if (rx > getWidth()) { rx = 0 - (int) paint.measureText(showString); } if (sweepAngle > 360) { sweepAngle = 0; } paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important rx = rx + 20; sweepAngle += 2; postInvalidate();//call by non-UI thread try { Thread.sleep(30);//important !!! } catch (InterruptedException e) { e.printStackTrace(); } } } } }
但要修改和重用會好難,所以要提取和封裝
0.change the name to BaseView
1. 在onDraw中,把
取出,put in to the new Method logic drawsub
void drawsub(Canvas canvas){ paint.setTextSize(200); canvas.drawText(showString, rx, 300, paint); canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true? } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawsub(canvas); if (myThread == null) { myThread = new MyThread(); myThread.start(); } //invalidate(); //cal by ui thread //postInvalidate(); //canvas.drawText("hi",rx,300,paint); }
2.in the MyThread run() method
pull out
if (rx > getWidth()) { rx = 0 - (int) paint.measureText(showString); } if (sweepAngle > 360) { sweepAngle = 0; } paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important rx = rx + 20; sweepAngle += 2;
put into logic method
void logic(){ if (rx > getWidth()) { rx = 0 - (int) paint.measureText(showString); } if (sweepAngle > 360) { sweepAngle = 0; } paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important rx = rx + 20; sweepAngle += 2; } public void run() { super.run(); while (running) { logic(); postInvalidate();//call by non-UI thread System.out.println("thread still running"); try { Thread.sleep(30);//important !!! } catch (InterruptedException e) { e.printStackTrace(); } } }
3. add protected abstract inforant of the logic and drawsub method
protected abstract void drawsub(Canvas canvas); protected abstract void logic();
4.Finally .BaseView
package pom.poly.com.trymakeviewbymyself.myView.v3; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.View; /** * Created by User on 14/10/2015. */ public abstract class BasicView extends View { private MyThread myThread = null; private boolean running = true; public BasicView(Context context) { super(context); } public BasicView(Context context, AttributeSet attrs) { super(context, attrs); } protected abstract void drawsub(Canvas canvas); @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (myThread == null) { myThread = new MyThread(); myThread.start(); } else { drawsub(canvas); } //invalidate(); //cal by ui thread //postInvalidate(); //canvas.drawText("hi",rx,300,paint); } protected abstract void logic(); @Override protected void onDetachedFromWindow() { running=false; super.onDetachedFromWindow(); System.out.println("in onDetachedFromWindow"); } class MyThread extends Thread { @Override public void run() { super.run(); while (running) { logic(); postInvalidate();//call by non-UI thread System.out.println("thread still running"); try { Thread.sleep(30);//important !!! } catch (InterruptedException e) { e.printStackTrace(); } } } } }
5. craet LogicView, extends Basae View, overide the logic and drawsub
package pom.poly.com.trymakeviewbymyself.myView.v3; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import java.util.Random; /** * Created by User on 14/10/2015. */ public class LogicView extends BasicView { private Paint paint = new Paint(); private int rx = 0; private Random random = new Random(); private String showString = "show me"; private RectF rectF = new RectF(0, 40, 600, 640); private float sweepAngle = 0; public LogicView(Context context) { super(context); } public LogicView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void drawsub(Canvas canvas) { paint.setTextSize(200); canvas.drawText(showString, rx, 300, paint); canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true? } @Override protected void logic() { if (rx > getWidth()) { rx = 0 - (int) paint.measureText(showString); } if (sweepAngle > 360) { sweepAngle = 0; } paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important rx = rx + 20; sweepAngle += 2; } }
Now,the view is more easy to change .
The finall important thing is , How to prevent the thread that we create keep run after exit then app?
protected void onDetachedFromWindow() { running=false; super.onDetachedFromWindow(); System.out.println("in onDetachedFromWindow"); }
onDetachedFromWindow call when view detach from the window
at this method,when we seat the boolean to false, the thread stop to loop.
制作自定義的View2-用view在Canvas畫動畫
In a View, the onDraw method use to draw the picture, So if we can call the onDraw many time per second, it become 動畫. However ,we cant call the onDraw directly , we need to use invalidate() or postInvalidate();
invalidate() VS postInvalidate();
invalidate call at UI Thread
postInvalidate call at non UI thread
Morever, we need to create a new thread to call postInvalidate to re Draw, in the onDraw method call invalidate is not good.
example:
https://github.com/roy989898/tryMakeViewByMyself
the v2 logic view
remark:
Thread.sleep(30);
is important, to prevent re flash too fast, you cant see the change
postInvalidate call at non UI thread
Morever, we need to create a new thread to call postInvalidate to re Draw, in the onDraw method call invalidate is not good.
example:
https://github.com/roy989898/tryMakeViewByMyself
the v2 logic view
remark:
Thread.sleep(30);
is important, to prevent re flash too fast, you cant see the change
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | package pom.poly.com.trymakeviewbymyself.myView.v2; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import java.util.Random; /** * Created by User on 14/10/2015. */ public class LogicView extends View { private Paint paint = new Paint(); private int rx = 0; private MyThread myThread = null; private String showString = "show me"; private RectF rectF = new RectF(0, 40, 600, 640); private float sweepAngle = 0; public LogicView(Context context) { super(context); } public LogicView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint.setTextSize(200); canvas.drawText(showString, rx, 300, paint); canvas.drawArc(rectF, 0, sweepAngle, true, paint);//why true? if (myThread == null) { myThread = new MyThread(); myThread.start(); } //invalidate(); //cal by ui thread //postInvalidate(); //canvas.drawText("hi",rx,300,paint); } class MyThread extends Thread { @Override public void run() { Random random = new Random(); super.run(); while (true) { if (rx > getWidth()) { rx = 0 - (int) paint.measureText(showString); } if (sweepAngle > 360) { sweepAngle = 0; } paint.setARGB(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));//important rx = rx + 20; sweepAngle += 2; postInvalidate();//call by non-UI thread try { Thread.sleep(30);//important !!! } catch (InterruptedException e) { e.printStackTrace(); } } } } } |
in this view, we create a new thread, However, when we leave the app, the thread still keep running. we will sole this problem next charcter.
訂閱:
文章 (Atom)