Add a ProgressBar into a custom view - android

I could not find tips or examples about how to do this. I want to add a progressbar over a Rect that I have already drawn, so how I can I do this?
Your answers will be truly appreciated! :)
Edited
public class MainView extends View {
public MainView(Context context) {
super(context);
}
public MainView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
logo.set(getPX(5), getPX(10), getPX(65), getPX(70));
background.set(getPX(30), getPX(2), canvas.getWidth() - getPX(10),
getPX(81));
canvas.drawRect(background, paint);
canvas.drawRect(logo, paint);
}
final private int getPX(float dp) {
return (int) (getResources().getDisplayMetrics().density * dp);
}
}

Based on your implementation (as you shown it to me):
<ScrollView .. >
<LinearLayout .. >
<MainView .. />
<MainView .. />
<MainView .. />
</LinearLayout>
</ScrollView>
my proposed solution would be - extend your CustomView class with LinearLayout (because then you can add additional views to your custom view):
public class MainView extends LinearLayout {
private Rect logo;
private Rect background;
public MainView(Context context) {
super(context);
setWillNotDraw(false); //needed in order to call onDraw method
logo = new Rect();
background = new Rect();
}
public MainView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
logo = new Rect();
background = new Rect();
RelativeLayout progressBarLayout = new RelativeLayout(context);
RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
ProgressBar progressBar = new ProgressBar(context, null, R.attr.progressBarStyleHorizontal);
progressBar.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
progressBar.setIndeterminate(true); //remove that (only for demonstration purposes)
lay.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
progressBarLayout.addView(progressBar, lay);
addView(progressBarLayout);
//Apart from the ProgressBar you are able to add as many views as you want to your custom view and align them as you would like
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
logo.set(getPX(5), getPX(10), getPX(65), getPX(70));
background.set(getPX(30), getPX(2), canvas.getWidth() - getPX(10),
getPX(81));
canvas.drawRect(background, paint);
canvas.drawRect(logo, paint);
}
final private int getPX(float dp) {
return (int) (getResources().getDisplayMetrics().density * dp);
}
}
In this example I am only showing how to add ProgressBar component, because that was your original question
You will need to add some more code in order to carry out your requirements (got from questioner):
P.S. This is just a solution to your particular problem/request. I would advise to use ListView component, which is better in the sense that it reuses views, so in such cases where you will have LOTS OF custom view instances, your application might become unusable, because there will be too much load on the activity class.
In order for you to migrate to using ListView component, try some examples first, like this

Related

Canvas DrawLine Is Invisible

I am trying to draw a single line in Android using canvas
My class :
public class LineDrawer extends View {
public LineDrawer(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(10);
float left = 20;
float top = 20;
float right = 50;
float bottom = 100;
canvas.drawLine(left, top, right, bottom, paint);
}
}
My Main Activity :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LineDrawer lineDrawer = new LineDrawer(this);
setContentView(R.layout.activity_Main);
}
}
I cannot find where is the problem , I try all the solutions in the internet but nothing happen , still a blank activity..
Should I import some code ?
lineDrawer is created but not added anywhere. Just creating a view is not enough, you need to add it to the current displayed views to be taken into account and drawn. You have two options:
Add it to your XML layout. You will have to add the following constructor to your custom view.
public LineDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
}
Use addView(). Anyway, given how simple is your example, I'll use first (common) method.
As an additional comment, the Paint paint object should be created on view initialization, as is a costly operation. See in the original documentation for more information about this.

Is it possible to use standart View in custom LinearLayout

I would like to add TextView and EditView into my custom LinearLayout programmatically.
But I don't know how.
Something like this (that doesn't work):
<com.custom.FavoritesViewer
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="#+id/favoritesViewer">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"/>
</com.custom.FavoritesViewer>
and my custom layout
public class FavoritesViewer extends LinearLayout {
private Bitmap fullImage;
private int canvasWidth;
private int canvasHeight;
private final Paint paint = new Paint();
public FavoritesViewer(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
initializeCanvasSize(context);
}
private void initializeCanvasSize(Context context) {
final Pair<Integer, Integer> screenSize = Utils.getScreenSize(context);
canvasWidth = screenSize.first;
canvasHeight = screenSize.second;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(canvasWidth, canvasHeight / 3);
}
#Override
protected void onDraw(Canvas cvs) {
if (fullImage == null) {
fullImage = Bitmap.createBitmap(canvasWidth, canvasHeight / 3, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(fullImage);
paint.reset();
paint.setColor(Color.parseColor("#AA000000"));
canvas.drawRect(0, 0, canvasWidth, canvasHeight / 3, paint);
}
cvs.drawBitmap(fullImage, 0, 0, null);
}
}
So I have a canvas (like background) and I would like to add some standart Views on top. I cannot add it on onDraw.
Is it any way to add View into custom Layout?
EDITTED
I need to implement some special UI with buttons. I want to wrap this in one component. I draw that UI on canvas and somehow should add buttons (It's enough for me to add simple ImageButton, not to draw an image and emulate button's behaviour). That's why I selected Layout as container and need to add Views programmatically.
As long as you call through to super (probably super.onDraw()), I imagine the parent class will draw the views you add as expected. It looks like you're just overriding onDraw, which would prevent the parent LinearLayout class from rendering it's content (like the TextView).
Try commenting out your onDraw method first, and see if the LinearLayout behaves as expected.
Also, what's the goal of the Custom Layout? There may be a better way to achieve your goal.

Skewing a text view in Android

I'm looking to replicate the following within my application:
As you can see, its basically a button which increases/decreases the value of the text view contained within it. This button will have three visual states -> unpressed, decrease and increase (as seen in the image above, the user taps the increase arrows and the button appears pressed in on that side)
Here are my 3 button states currently:
As you can see, the problem I have is being able to correctly skew/rotate the text view so it looks visually correct and appears slanted along with the button when its being increased or decreased.
I have tried two different approaches so far:
Create a custom text view class which overrides the onDraw() method to skew the canvas:
#Override
public void onDraw(Canvas canvas) {
canvas.save();
canvas.skew(0.2f, 0f);
super.onDraw(canvas);
canvas.restore();
}
Integrate the Rotate3dAnimation class (source here) and used many different variations to get the desired result such as:
Rotate3dAnimation skew = new Rotate3dAnimation(
30, 0, centerX, centerY, 0, false);
txtAmount.startAnimation(skew);
Unfortunately, I'm not quite getting the exact result that mirrors the first image above. I'm getting confused with setting values with the Z-axis, skew, rotate etc.
I'd greatly appreciate any help from anyone who has experience with this stuff. Thanks in advance
Well I even tried and I came up with something like this:
public class DemoActivity extends TextView {
Context context;
String firstText = "$120.00";
public DemoActivity(Context context)
{
super(context);
this.context = context;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
setText(firstText);
setTextSize(30);
canvas.skew(1.0f, 0.3f); //you need to change values over here
Rotate3dAnimation skew = new Rotate3dAnimation(
-20, 30,200, 200, 0, false); //here too
startAnimation(skew);
}
}
I got an output as:
I guess changing the values by trial and error can solve your problem.
Hope it helps.
Thanks to Parth Doshi answer. His answer need a little tweaking to run which I'm sharing here to save someone else time.
First create a class in src folder and write all of three constructors.
public class TextViewDemo extends TextView {
Context context;
String text = "TESTING 3DX TOOLS";
public TextViewDemo(Context context) {
super(context);
this.context = context;
}
public TextViewDemo(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public TextViewDemo(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.context = context;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
setText(text);
setTextSize(30);
canvas.skew(0.5f, 1.0f); // you need to change values over here
Rotate3dAnimation skew = new Rotate3dAnimation(-50, 30, 0, 0, 0,
false); // here too
startAnimation(skew);
}
}
In you res/layout/my_layout.xml file you can add a tag of your custom made TextView.
<com.yourpackage.name.TextViewDemo
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Hello World"
<!-- All parameters and value shall remain same -->
/>
Like any other view, you can create an instance of TextViewDemo in your onCreate() method
TextViewDemo txtDemo = (TextViewDemo) findViewById(R.id.name);
Regards

Creating a custom compound view

I'm trying to create a view that has an ImageView with a TextView on top of it.
I'm stuck trying to find any good examples on this so I'm hoping someone can tell me what I've done wrong or where to look for examples. I've seen http://developer.android.com/guide/topics/ui/custom-components.html#compound but only really describes the minimal requirements.
I've found a couple things like Creating Compound Controls With Custom XML Attributes but my setup is a tad different.
My code is below, which extends LinearLayout and am not sure if that is even the way to go. Nothing displays in the layout.
ImageWithOverlay
public class ImageWithOverlay extends LinearLayout {
ImageView image;
TextView text;
public ImageWithOverlay(Context context) {
super(context);
setupDisplay(context);
}
public ImageWithOverlay(Context context, AttributeSet attrs) {
super(context, attrs);
setupDisplay(context);
}
public ImageWithOverlay(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupDisplay(context);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
image.draw(canvas);
text.draw(canvas);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void setupDisplay(Context context) {
image = new ImageView(context);
image.setImageResource(R.drawable.flowers);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
image.setLayoutParams(lp);
text = new TextView(context);
text.setText("testing");
lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
text.setLayoutParams(lp);
}
}
status.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.package.blah.ImageWithOverlay
android:id="#+id/imageWithOverlay1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</com.package.blah.ImageWithOverlay>
</RelativeLayout>
Use a RelativeLayout instead of a LinearLayout, this will allow you to place the text over the image.
The reason why they aren't appearing is that they haven't been added using addView, so call this after you've set each one's LayoutParams.
Remove the onDraw() call, this isn't used for ViewGroups unless you explicitly request it do be. And once the Views are added they'll be drawn automatically.

Need help with drawing on a custom made view

I need your experience.
Problem : I need to be able to draw thing (rect, circ,etc) on one part of a FlipperView....
My main.xml has a main linearLayout. In this LinearLayout I have a ViewFlipper with 2 linearlayouts in it. The first linearlayout has soms buttons, inputfiels,etc... the second one should have a special view in wich I can draw the things I choose in the first part.
So I have created a new view wich extends the View class so I can play with the ondraw methode. But I can not get it to work.
This is what I have so far...
MAIN.XML
<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="#+id/layout_main" xmlns:android="http://schemas.android.com/apk/res/android">
<ViewFlipper android:id="#+id/details" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="vertical" android:layout_height="match_parent">
//BUTTONS TEXTFIELDS ETC
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="vertical" android:layout_height="match_parent">
//an instance of my new ViewClass
<Vierbergen.Tim.ViewClass
android:id="#+id/draw" android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
The VIEWCLASS.java
public class ViewClass extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
paint.setColor(Color.WHITE);
}
#Override
public void onDraw(Canvas canvas) {
//depending on some params....
draw this, draw that...
}
}
and then my main activity
DRAWER.JAVA
public class SmsDraw extends Activity implements OnTouchListener{
ViewClass vClass;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
vClass = (ViewClass) findViewById(R.id.draw);
}
// with somewhere a draw function excecuted by a button
private void start() {
//where can I get a canvas ? Canvas c = new Canvas();
blablalba
vClass.onDraw(c);
}
So I need to be able to draw on the thing VIEWCLASS with id = draw in my main.xml...
How can I do this ? please help me with an explanation and solution and not just a solution :-)
Thanks VeeTee
Your onDraw method will be called by the framework if your View is attached to the view hierarchy. You don't need to call it yourself.
If you're unsure about your onDraw code, try using the code from a sample like DrawPoints in API Demos.
You don't call onDraw yourself, as Matthew has said. Here's a very simple addition to your ViewClass that would allow you to draw rectangles or circles. It hasn't been tested, so proceed carefully.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class DrawView extends View {
private boolean drawRect;
private boolean drawCircle;
private float rect_w;
private float rect_h;
private int rect_color;
private float circle_radius;
private int circle_color;
Paint paint;
public DrawView(Context context) {
super(context);
paint = new Paint();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
}
public void drawRect(float w, float h, int color) {
// define these variables privately at the top of the class
this.drawRect = true;
this.drawCircle = false;
this.rect_w = w;
this.rect_h = h;
this.rect_color = color;
}
public void drawCircle(float radius, int color) {
// define these variables privately at the top of the class
this.drawRect = false;
this.drawCircle = true;
this.circle_radius = radius;
this.circle_color = color;
}
#Override
public void onDraw(Canvas canvas) {
if (drawRect) {
paint.setColor(this.rect_color);
canvas.drawRect(0, 0, rect_w, rect_h, paint);
}
if (drawCircle) {
paint.setColor(this.circle_color);
canvas.drawCircle(0, 0, circle_radius, paint);
}
}
}
Then in your view Class, call it like this:
vClass = (DrawView) findViewById(R.id.draw);
vClass.drawRect(3,4,0x334434);
Seems like the problem it wasn't working the first time was...
when the main activity want to setContentView(...)... it crashes....
But when I leave it out of the xml
and create it at runtime like this
viewClass = new ViewClass(this);
layke = (LinearLayout) findViewById(R.id.layoutDraw);//wich is the second part of the flipperview
layke.addView(viewClass); // to at it to the right layout
it works....

Categories

Resources