How to add custom view to the layout? - android

I have a GraphicsView class that extends from the View class and I want to add this GraphicsView class to the main layout in my project. How can I do that?
static public class GraphicsView extends View {
public GraphicsView(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
// Drawing commands go here
Path rect = new Path();
rect.addRect(100, 100, 250, 50, Direction.CW);
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
canvas.drawPath(rect, cPaint);
}
}
and my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linnnnlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<TextView
android:id="#+id/Customfont"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
<View
android:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

You need to give complete path of your class that extends View,
<com.blah.blah.GraphicsView
android:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

If I remember correctly, you need to provide more constructors to use view from xml file (add it to xml file like "Me and We" suggested).
public GraphicsView(Context context) {
super(context);
}
public GraphicsView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GraphicsView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
Update: fixed code.

i finaly got it here is the code
the XML code
<com.customfonts.namespace.BreakDownBar
android:id="#+id/gview"
android:layout_width="fill_parent"
android:layout_height="20dip"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:background="#color/BreakDownBarBack"/>
and the class
package com.customfonts.namespace;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.util.AttributeSet;
import android.view.View;
public class BreakDownBar extends View {
public BreakDownBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
//Draw rectangle;
Path rect = new Path();
rect.addRect(0, 0,250, 150,Direction.CW);
Paint cpaint = new Paint();
cpaint.setColor(Color.GREEN);
canvas.drawPath(rect, cpaint);
}
}

you need to do this:
LinearLayout v = (LinearView) findViewById(R.id.linnnnlayout);
GraphicsView myView = new myGraphicsView(this);
v.addView(myView);

Because your custom View is an inner class in your Activity the java compiler will output the name ActivityName$GraphicsView for that class. You can't use that name directly as the View name in the xml layout because of the $ character but you can do it like this:
<view
class="com.package.here.ActivityName$GraphicsView"
android:id="#+id/view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
where ActivityName is the name of the activity where your GraphicsView class is declared.

public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout v = (LinearLayout) findViewById(R.id.linearLayout);
MyGraphics myView = new MyGraphics(this);
v.addView(myView);
}
}
public class MyGraphics extends View {
public MyGraphics(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
// Drawing commands go here
Path rect = new Path();
rect.addRect(100, 100, 250, 50, Direction.CW);
Paint cPaint = new Paint();
cPaint.setColor(Color.LTGRAY);
canvas.drawPath(rect, cPaint);
}
}
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/linearLayout">
<TextView
android:id="#+id/Customfont"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello" />
</LinearLayout>

This is working for me and add the view in XML with full path and try giving wrapcontent for height and width.
public class RectangleView extends View {
public RectangleView(Context context) {
super(context);
}
public RectangleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RectangleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.GRAY);
canvas.drawColor(Color.BLUE);
canvas.drawRect(10,10,50,50, paint);
}
}

Related

I can't get my custom SurfaceView on top in Android

I have 3 views:
GLSurfaceView
Custom SurfaceView
View
The GLSurfaceView is at the bottom
The Custom SurfaceView should be above and on the top
The View is above and on the bottom
This is my code:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
GameGlSurfaceView gameGlSurfaceView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameGlSurfaceView = new GameGlSurfaceView(this);
setContentView(gameGlSurfaceView);
View hudView = getLayoutInflater().inflate(R.layout.activity_main, null);
addContentView(hudView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
View inpudPadView = getLayoutInflater().inflate(R.layout.input_pad, null);
LinearLayout.LayoutParams inpudPadViewParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
inpudPadViewParams.gravity = Gravity.TOP;
addContentView(inpudPadView, inpudPadViewParams);
}
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SurfacePanel extends SurfaceView implements SurfaceHolder.Callback {
Context context;
Bitmap bitmapTest;
MyThread mythread;
public SurfacePanel(Context ctx, AttributeSet attrSet ) {
super(ctx, attrSet);
context = ctx;
bitmapTest = Bitmap.createBitmap(200, 100, Bitmap.Config.ARGB_8888);
bitmapTest.eraseColor(Color.TRANSPARENT);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
void doDraw(Canvas canvas) {
canvas.drawColor(Color.GREEN);
canvas.drawBitmap(bitmapTest, 50, 10, null);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
mythread = new MyThread(holder, context,this);
mythread.setRunning(true);
mythread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mythread.setRunning(false);
boolean retry = true;
while(retry) {
try {
mythread.join();
retry = false;
}
catch(Exception e) {
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="de.batechniks.surfaceviewtest.MainActivity">
<de.batechniks.surfaceviewtest.SurfacePanel
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/textView"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:baselineAligned="false"
xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="left">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/bt_down"
android:src="#mipmap/ic_launcher"
android:layout_gravity="bottom"/>
</LinearLayout>
The result is: I can see the GLSurfaceView and i can see the view above on the bottom.
On the top, i only see the textview "Large Text". The SurfaceView is not shown.
When i uncomment setContentView(gameGlSurfaceView), the SurfaceView is shown.
The main problem is to show the SurfaceView, the second problem will be to get the SurfaceView transparent.
Thanks a lot
You need to call the method
this.setZOrderOnTop(true);
in your constructors.
It's recommended to do constructors in custom views like this
public SurfacePanel (Context context) {
super(context);
init();
}
public SurfacePanel (Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SurfacePanel (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#TargetApi(21)
public SurfacePanel (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
if(!isInEditMode()) {
this.setZOrderOnTop(true);
}
}

SurfaceView failed to instantiate

I'm trying to implement a custom SurfaceView in my activity's XML file, and then reference it within the activity's code for drawing etc. However, I'm getting the following error:
The following classes could not be instantiated:
- com.example.animateddrawable.MainActivity.DrawingPanel
MainActivity Code:
package com.example.animateddrawable;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
...
com.example.animateddrawable.MainActivity.DrawingPanel.PanelThread;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dp = new DrawingPanel(this, null);
setContentView(R.layout.activity_main);
}
public class DrawingPanel extends SurfaceView implements SurfaceHolder.Callback {
public DrawingPanel( Context context, AttributeSet attributeSet){
super(context, attributeSet);
init();
}
public void init(){
getHolder().addCallback(this);
}
}
}
XML Code
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.animateddrawable.MainActivity.DrawingPanel
android:id="#+id/surfaceView"
android:layout_width = "fill_parent"
android:layout_height = "fill_parent"/>
</FrameLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</LinearLayout>
Any ideas?
try to add a constructor like this:
public DrawingPanel(Context context) {
super(context);
getHolder().addCallback(this);
}
public DrawingPanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
getHolder().addCallback(this);
}
add this to your other constructer as well:
getHolder().addCallback(this);

Android draw on canvas

New to Android development, and I'm having trouble doing a simple drawing to a view using a canvas.
From what I've understood, something like this:
import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
public class DrawView extends View
{
public DrawView(Context context)
{
super(context);
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
canvas.drawRGB(255,0,0);
}
}
With this as my Activity:
public class Prototype1 extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
And this for the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.dhs2.prototype1.DrawView
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Should just draw red everywhere, but instead I just get a blank screen.
Any idea where I'm going wrong?
Since you added your custom view in an XML layout file, you should add 2 more constructors:
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
}
This is because you pass some attributes to the view, like fill_parent, wrap_content, so the constructor public DrawView(Context context) won't be called.
This would work however, if you won't declare your custom view in the XML layout file, but setting it directly from the onCreate() like this:
setContentView(new DrawView(this));

It is possible to set the text of a "TextView" from within a class 'extends View'

I've insert a custom View called "disegno" inside a Layout xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?windowsBackground">
<it.package.myapp.Disegno
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/finestraDisegno"
android:isScrollContainer="true" />
<FrameLayout
android:layout_height="0dp"
android:layout_width="0dp"
...
<EditText
...
android:id="#+id/et_MOD_x">
</EditText>
Then I've implemented the extends View class for populate the custom layout:
package it.package.myapp;
import android.content.Context;
...
public class Disegno extends View {
public Disegno(Context context) {
this(context, null, 0); }
public Disegno(Context context, AttributeSet attrs) {
this(context, attrs, 0);
setContentView(R.layout.main); }
public Disegno(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
init(attrs); }
...
#Override
protected void onDraw(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
// chiamo routine assi cartesiani
AssiCartesiani(canvas);
// chiamo routine polilinea
Polilinea(canvas); }
...
Now I would to set the text of the textView "et_MOD_x" by "findViewById(R.Id.et_MOD_x)" changing the code like this:
#Override
protected void onDraw(Canvas canvas) {
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor);
// chiamo routine assi cartesiani
AssiCartesiani(canvas);
// chiamo routine polilinea
Polilinea(canvas);
EditText et_MOD_x = (EditText) findViewById(R.Id.et_MOD_x)
et_MOD_x.setText("abcd");
}
but without "setContentView(...)" is not possible!
Summing: I would to set the text of a "EditText" from within an "extends View" class. I'd to pointing to an external layout... mmmhh!
There is any way to do this?!
have a reference in your custom view
public class Disegno extends View {
private TextView textView;
public void setTextView(TextView tv){
textview = tv;
}
#Override
protected void onDraw(Canvas canvas) {
textview.setText("Your text here!")
}
}
in your Activity.onCreate()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.my_layout);
EditText et_MOD_x = (EditText) findViewById(R.Id.et_MOD_x);
Disegno finestraDisegno = (Disegno)findViewById(R.Id.finestraDisegno);
finestraDisegno.setTextView(et_MOD_x) ;
}
May be this is not the right way but you can :
Get your editText in your activity and declare it as static.
public static EditText et_MOD_x;
et_MOD_x = (EditText) findViewById(R.Id.et_MOD_x)
and In your View class set the text by :
YourActivity.et_MOD_x.setText("abcd");
Hope it helps..

Subclass of TextView and text color

I'm trying to implement a subclass of TextView that prints the text vertically rotated, but I'm having troubles printing the text in the color I specify from an XML layout. The class code is:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.TextView;
public class VerticalTextView extends TextView {
private Rect bounds = new Rect();
private TextPaint textPaint;
public VerticalTextView(Context context) {
super(context);
}
public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
textPaint = getPaint();
textPaint.getTextBounds((String) getText(), 0, getText().length(), bounds);
setMeasuredDimension((int) (bounds.height() + textPaint.descent()), bounds.width());
}
#Override
protected void onDraw(Canvas canvas) {
canvas.rotate(-90, bounds.width(), 0);
canvas.drawText((String) getText(), 0, -bounds.width() + bounds.height(), textPaint);
}
}
I have no need of custom properties for this view, so I'm not declaring a styleable for it.
I'm using this view in my activity by this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.verticaltextview.VerticalTextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Hello World" android:textColor="#ff0000ff"
android:textStyle="italic" />
</LinearLayout>
As you can see, I'm specifying both the text color (blue) and the text style (italic), but only the style is applied, as the text is printed in black. If in the onDraw() method I hardcode a color by doing textPaint.setColor(0xff00ff00), then the text is correctly printed in color.
Suggestions? Thanks ;)
You will have to change the constructors of your VerticalTextView to the following:
private int col = 0xFFFFFFFF;
public VerticalTextView(Context context, AttributeSet attrs)
{
super(context, attrs); // was missing a parent
col = getCurrentTextColor();
}
Then add
textPaint.setColor(col);
to your onDraw() function.
Hope this helps.
i think you can get color in:
**public VerticalTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}**
then set this color to textPaint.

Categories

Resources