For example i have a layout (or view in a layout) that covers %20 percent of height of the screen.I want to add a drawn canvas to that part. But I dont want to use it with setContentView because i can not do my layout operations such as textviews and edittexts etc. So how can i add that custom class to my layout. LinearLayout.addView(My custom -view extended- class) does not work.
Note: Scale must be lowered proportionally, for example if i draw it for fullscreen, when adding the scale must be lowered to fit that covered area.
This Works but not desired
DrawShape ds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
ds = new DrawShape(this);
setContentView(ds); // Dont want it
}
class DrawShape extends View {
Context c;
Paint p = new Paint();
public DrawShape(Context c)
{
super(c);
this.c = c;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = canvas.getWidth();
int height = canvas.getHeight();
p.setStyle(Paint.Style.STROKE);
p.setAntiAlias(true);
p.setStrokeWidth(width/40);
p.setColor(Color.rgb(200,140,0));
RectF r = new RectF();
r.set(width/4,height/2-width/4,width-(width/4),height/2+width/4);
canvas.drawCircle(width / 2, height / 2, width / 4, p);
canvas.drawLine(0,0,width,height,p);
canvas.drawLine(width,0,0,height,p);
canvas.drawLine(0,height/2,width,height/2,p);
}
}
This does not work, no draw
LinearLayout ll;
DrawShape ds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
ds = new DrawShape(this);
setContentView(R.layout.activity_main);
ll = (LinearLayout) findViewById(R.id.mainLL);
mainLL.addView(ds); // Does not work, with layout params it does not work too.
}
Related
I currently have the following layout as part of my XML file:
LinearLayout (orientation: vertical)
+---TextView (title)
+---LinearLayout (orientation: horizontal)
+---ConstraintLayout
+---...
+---ConstraintLayout
+---...
+---ConstraintLayout
+---...
The parent LinearLayout has a background that is a drawable.
My intention is to have the child TextView and child LinearLayout tint a part of said parent LinearLayout's background each with different colors.
I've tried the backgroundTint and foregroundTint attributes in both the child layouts, but neither changed the parent LinearLayout's drawable in any way.
So, is there any way I can do what I asked in the title, or am I stuck subclassing the LinearLayout and overriding the onDraw function?
Yup, I'm stuck with using the ViewGroup's onDraw function:
public class PartialTintedRoundedRectLinearLayout extends LinearLayout {
Context ctx;
RectF topPartitionRect, botPartitionRect;
RectF topBandAidRect, botBandAidRect;
Paint bgTopPaint, bgBotPaint;
int defaultCornerRadius;
float material30sdp;
public PartialTintedRoundedRectLinearLayout(Context c) {
super(c);
init(c);
}
public PartialTintedRoundedRectLinearLayout(Context c, AttributeSet a) {
super(c, a);
init(c);
}
public PartialTintedRoundedRectLinearLayout(Context c, AttributeSet a, int dsAttr) {
super(c, a, dsAttr);
init(c);
}
private void init(Context c) {
setWillNotDraw(false);
ctx = c;
defaultCornerRadius = (int)(20 * ctx.getResources().getDisplayMetrics().density);
material30sdp = ctx.getResources().getDimension(R.dimen._30sdp);
bgTopPaint = new Paint(); bgTopPaint.setColor(ContextCompat.getColor(ctx, R.color.blue_700));
bgBotPaint = new Paint(); bgBotPaint.setColor(ContextCompat.getColor(ctx, R.color.blue_500));
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
topPartitionRect = new RectF(0, 0, getWidth(), material30sdp);
topBandAidRect = new RectF(0, defaultCornerRadius, getWidth(), material30sdp);
botPartitionRect = new RectF(0, material30sdp, getWidth(), getHeight());
botBandAidRect = new RectF(0, material30sdp, getWidth(), getHeight() - defaultCornerRadius);
invalidate();
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRoundRect(topPartitionRect, defaultCornerRadius, defaultCornerRadius, bgTopPaint);
canvas.drawRoundRect(botPartitionRect, defaultCornerRadius, defaultCornerRadius, bgBotPaint);
canvas.drawRect(topBandAidRect, bgTopPaint);
canvas.drawRect(botBandAidRect, bgBotPaint);
}
}
I'll have to figure out how to make it more general, since this was made for one specific use-case.
If you observe the above two pictures, there are markers in picture1, if user tap on marker second picture will come with available options dynamically may be 2,3 etc.
For the second picture I have written custom view and able to draw circle but unable to show images inside the circle.
public class CustomView extends ViewGroup {
private Paint paint;
public CustomView(Context context) {
super(context);
// create the Paint and set its color
paint = new Paint();
paint.setColor(0xFF1f5b83);
}
#Override
protected void dispatchDraw(Canvas canvas) {
int width = this.getWidth();
int height = this.getHeight();
canvas.drawCircle(width / 2, height / 2-64, 200, paint);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
}
For testing purpose I am adding text instead of image
public void sendMessage(View view) {
circleView = new CustomView(this);
TextView textView = new TextView(this);
textView.setText("Test");
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.WHITE);
addContentView(circleView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
circleView.bringToFront();
}
How to add images inside the circle in Java class I mean Activity class?
Hi im trying to get my app to update a canvas from a custom view i made
This view creates a square with lines and a circle in the center.
I want to press a button and draw random x and y coordinates to the canvas.
Heres My MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// EditText numDart = (EditText) findViewById(R.id.numDarts);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public int convertToDpi(int px){
DisplayMetrics metrics = getResources().getDisplayMetrics();
int unit = metrics.widthPixels/20;
return px * unit;
}
public void drawCanvas(View v){
View view = (View) findViewById(R.id.canView);
Paint black = new Paint();
black.setColor(Color.BLACK);
black.setStyle(Style.FILL);
view.invalidate(); //dont know where to go from here
}
Heres My Custom View:
public CanView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Rect myrect = new Rect();
myrect.set(-10, 10, 10, -10);
Paint blue = new Paint();
Paint white = new Paint();
white.setColor(Color.WHITE);
white.setStyle(Paint.Style.FILL);
Paint black = new Paint();
black.setColor(Color.BLACK);
black.setStyle(Paint.Style.FILL);
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(myrect, blue);
canvas.drawCircle(convertToDpi(10), convertToDpi(10),convertToDpi(3), white);
canvas.drawLine(convertToDpi(10), 0, convertToDpi(10), convertToDpi(20), black);
canvas.drawLine(0, convertToDpi(10), convertToDpi(20), convertToDpi(10), black);
canvas.scale(5, 5, 0, 0);
}
#Override
public void postInvalidate() { //Logic for redrawig goes here???
// TODO Auto-generated method stub
super.postInvalidate();
}
public int convertToDpi(int px){
DisplayMetrics metrics = getResources().getDisplayMetrics();
int unit = metrics.widthPixels/20;
return px * unit;
}
I dont get how to reference the canvas from my Custom View and change or redraw it. Im assuming you use invalidate(); but im puzzled on how this method works can any1 help me out?
When invalidate is called onDraw is called again, you should also use this.getHolder().addCallback(this); and let your class implement Callback and add the unimplemented methods
I guess you need to draw the view only. First of set your contentview as the View where you are drawing on the canvas. Your are setting your contnet view only as the main layout. If you want to see the View where you drawing on canvas. set that view to your contentView.
setContentView(canView);
Now if you want that button too, then create a relative layout and add the button view and this canView to that relative layout ans set this as your contentView.
I have a relative layout inside a scrollview, then i created a new view with this code:
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLACK);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(5, 5, 140, 140, paint);
}
}
Then i try to use layout.addView(DrawView) to add the new view to the relative layout, so it can be scrollable with the rest of the content, but is doesn't work, nothing shows up..
Am i missing something ?
Edit:
DrawView formas;
GifMovieView gif;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final RelativeLayout layout = new RelativeLayout(this);
final ScrollView scrollView = new ScrollView(this);
//gif = new GifMovieView(this, t_img);
formas = new DrawView(this);
layout.addView(formas);
scrollView.addView(layout);
this.setContentView(scrollView);
inicializar();
load(layout);
}
You will probably want to override onMeasure() in your DrawView. Otherwise your view will have size of 0x0 pixels.
You can start with something as simple as
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(200, 200);
}
just to prove it works, but you will need to do some more meaningful, based on what are contents of your view.
Start from this article to see help on overriding onDraw() and onMeasure()
When I comment out setContentView(boardView); in my Game.java my custom view in BoardView works fine and displays everything nicely... but onSizeChanged never gets called in BoardView.java... so I can't read the device width and height at runtime. If I leave setContentView uncommented onSizeChanged works... but the screen is blank!
I want to be able to read the screen width and height at runtime and set the sizes of my ImageViews at creation so they are the optimal size.
public class Game extends Activity implements OnClickListener{
private BoardView boardView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boardView = new BoardView(this);
setContentView(boardView); // when this line disabled, it looks ok
boardView.requestFocus();
}
public class BoardView extends View {
private final Game game;
private float width; // width of one unit
private float height; // height of one unit
public BoardView(Context context){
super(context);
this.game = (Game)context;
setFocusable(true);
setFocusableInTouchMode(true);
LinearLayout maincontainer = new LinearLayout(game);
maincontainer.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
maincontainer.setGravity(Gravity.CENTER);
maincontainer.setOrientation(LinearLayout.VERTICAL);
maincontainer.setBackgroundColor(Color.BLACK);
LinearLayout innercontainer = new LinearLayout(game);
innercontainer.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
innercontainer.setGravity(Gravity.CENTER);
innercontainer.setOrientation(LinearLayout.HORIZONTAL);
// declare a new table
TableLayout layout = new TableLayout(game);
layout.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
// build a grid of ImageViews in a TableLayout
for (int f=1; f<=7; f++) {
TableRow tr = new TableRow(game);
for (int c=1; c<=7; c++) {
ImageView b = new ImageView(game);
b.setImageResource(R.drawable.neworb);
b.setOnClickListener(game);
tr.addView(b, 30,30); // I'd like to not use fixed values here
} // for
layout.addView(tr);
} // for
innercontainer.addView(layout);
maincontainer.addView(innercontainer);
game.setContentView(maincontainer);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
width = w/9f;
height = width;
super.onSizeChanged(w, h, oldw, oldh);
}
}
}
Thought I solved my own problem. I was neglecting to place my my view building code withing the Overriden onDraw method. i.e.:
#Override
protected void onDraw(Canvas canvas)
{
LinearLayout maincontainer = new LinearLayout(this.game);
// etc..
I was just including it within the main class and not Overriding onDraw... which you gotta do when you extend View.