How do I call a custom class in an Activity? - java

So I have this DrawAnim.java class file and I want to use its content inside my MainAcitivty. I tried creating an object like this:
DrawAnim draw;
And in onCreate method, I did this:
draw.onDraw(); <- I know I have to pass a parameter but don't know what to pass on.
Here's my class:
public class DrawAnim extends View {
Bitmap ball;
int x, y;
public DrawAnim(Context context) {
super(context);
ball = BitmapFactory.decodeResource(getResources(), R.drawable.globe);
x=0;
y=0;
}
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Rect ourRect = new Rect();
ourRect.set(0,0,canvas.getWidth(),canvas.getHeight()/2);
Paint red = new Paint();
red.setColor(Color.RED);
red.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect,red);
if( x < canvas.getWidth()) {
x += 10;
} else{
x =0;
}
if( y < canvas.getHeight()){
y+=10;
}else{
y =0;
}
Paint p = new Paint();
canvas.drawBitmap(ball,x,y,p);
invalidate();
}
}

You've extended a View, so you must use it like any other view, either by adding it programmatically at runtime or using it in a layout.

Here is how to add a view in the code. The following steps should be added to the onCreate method of the splash activity.
Get the Layout where the view will be added to in the code, something like LinearLayout linearLayout = findViewById(R.id.linearlayout); (It of course has to be change to your layout and layout-id)
Create an instance of the DrawAnim
Add it to the layout by linearLayout.addView(drawAnim);
Hope this gives an idea and helps.
Here is a link to an animated splashscreen and a link to a very simple splashscreen just to show some alternatives to adding a view. Although the 2nd one is very limited it has a bit animation and does not delay the start of your app.

You should add it like any other views, pass context to your custom view constructor, set Layout params and add it to the parent view group.
DrawAnim draw = new DrawAnim(this); // 'this' as a context in activity
draw.setLayoutParams(layoutParams);
parentViewGroup.addView(draw);

Related

How to display a simple ImageButton on a customly created view?

I've been browsing the entire internet, but I could not find any answer to this question. I want to create a background, some image buttons, along with a bunch of moving graphics (circles). Since I do not know how to overwrite a xml layout with moving graphics, I chose to customly create my view, draw the background, the imageButtons and the circles (2D graphics).
public class GameView extends View implements UtilConstants
since I extended the View class, I had to call the super class constructor in my constructor
GameView(Context context) {
super(context);
this.context = context;
this.paint = new Paint();
}
and to implement the onDraw method, which acts like the java paintComponent
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); // necessary for some reason
setGridBackground(); // sets the background
paint.setColor(Color.parseColor("#FF0000"));
canvas.drawCircle(this.x += 10, 300, 20, paint); //moves my graphics (ball) within the screen
drawScoreInLeftUpperCorner(canvas, 20); // paints a string text on the screen
setAbilitiesImages(); // places some imageButtons
try {
Thread.sleep(THREAD_REFRESH_RATE_MS);
} catch (InterruptedException ex) {
System.out.println(ex);
}
invalidate();
}
Now, to get to my problem:
I do not know how to set those ImageButtons !!! I am trying
private void setAbilititesImages() {
ImageButton imageButton = new ImageButton(this.context); // is this ok to put the argument this.context??
imageButton.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
imageButton.setImageResource(R.drawable.monster); // set my resource
RelativeLayout relativeLayout = findViewById(R.id.in_game_layout); // what is the purpose of this???
if (relativeLayout != null) { // it never enters this if, relativeLayout is always null
relativeLayout.addView(imageButton);
}
}
Aaaaand the image button never shows up...why is it necessary to use Relative/Linear layouts? That R.id.in_game_layout I created is just an empty RelativeLayout xml. Can't I just use something like
imageButton.setImageResource(R.drawable.monster); // set my resource
imageButton.setBounds(.....);
(View)this.add(imageButton); ???
ImageButton requires a parent view to be hosted in it. The parent View can be a RelativeLayout, a linearlayout or a ConstraintLayout.
In your case, the instance relativeLayout is always null because you not specify the view parent in which you do findViewById.
You should make something like :
RelativeLayout relativeLayout = view.findViewById(R.id.in_game_layout);
You need to add layout param to your parent Relative layout also to display your Image button appropriately.
Example
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ImageButton imageButton = new ImageButton(this);
imageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_background,null));
relativeLayout.addView(imageButton,params);

Drawing a shape?

I have tried to draw a shape for a long time without an answer. I used setContentView(view) for that view. However, I have another setContentView:
setContentView(R.layout.activity_main);//Buttons, Views from XML...
setContentView( mCustomDrawableView);//Custom Shape
Problem is, it only shows ONE view, the shape. The Buttons defined on XML are gone. Basically whichever setContentView(view) is called last is the only View who is drawed. I've also tried many other ways to draw the shape without an answer that works.
I have seen that multiple setContentView do overlap each other, but this is the only way that partially works. Any way to display both Views or another way to draw a shape and my XML Views?
EDIT:
My shape is made in java, not XML
EDIT 2:
Here is my customShape Class:
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context context) {
super(context);
int x = 10;
int y = 10;
mDrawable = new ShapeDrawable(new RectShape());
// If the color isn't set, the shape uses black as the default.
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x,y,x+10,y+10);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
OK ... setContentView is something which takes a layout/view/whatever and the input defines the contents of the activity/fragment your are setting it to.
So of course your first call does the whole layout, and the second wipes that and sets the content to what you're sending to it.
The thing is to have your view and then add it to a layout. If you have any view in your initial setContentView xml named (+id) and defined (Layout x = getfromid(r.id.x) you can then add your view to that layout with x.addview(myview) or x.addview(CustomDrawableView(context)).
-edit for clarification-
An Activity/Fragment has a Layout which you set using setContentView. You do this once, normally. A Layout defines where Views are placed.
So, you setContentView(your.xml) in onCreate. If you have a programmatic View class, you can then do two things: add new YourView to a named and specified layout in your act/frag (using any layout defined in xml, passed to your frag/act in the xml passed in setContentView and then defined by Layout x = findViewById(R.id.idoflayoutinxmlinfield 'android:id="#+id/x") in code.
Then you can x.addview(new MyView(context)) or Myview z = new MyView(context) and x.addView(z);
-edit2-
When you get better, you can also just add your custom View to the original layout by adding it to the original xml definition.
-edit3-
Sigh. OK. Here it is:
In your activities java file:
RelativeLayout myRellayout;
#Override
public void onCreate(){
setContenView(your.xml)
myRelLayout = findViewByID(R.id.myrellayout);
myRelLayout.addView(new MyCustomView(this));
//or define your custom view and the add it by:
//MyCustomView mcv = new MyCustomView(this);
//myRelLayout.addView(mcv);
}
And your xml should contain any layout like this:
<RelativeLayout
android:id="#+id/myrellayout"
android:width="whatever"
android:height="whatever"
/>

Alter canvas with a button click in the main activity

I am struggling with the logic behind this, so any tips would be appreciated. I have two classes, one in which the fragment is created and one in which my custom view is created, and I am trying to do some animation. In the main layout, I have an edit text field and a button. What I want to do is to add to the custom view when a button is clicked, the text within the edit text will be added to the custom view. Thinking about HOW to do this, I am drawing a blank, and I am beginning to think it is not possible. Should I just create the edit text within the custom view? Here is the code showing what I am doing (but stuck on a next step, or whether or not I should scrap this approach and try a different one)
The main fragment
public class DestroyerView extends Fragment
{
private Context mContext;
Paint paint = new Paint();
private AnimatedNegative PositiveAnimatedNegative;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mContext = this.getActivity();
View view = inflater.inflate(R.layout.activity_destroyer, container, false);
final Button fire = (Button) view.findViewById(R.id.destroy);
PositiveAnimatedNegative = (AnimatedNegative) view.findViewById(R.id.anim_view);
fire.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
// logic here?
}
});
return view;
}
}
public AnimatedNegative(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = this.getContext();
h = new Handler();
mCalendarDbHelper=new CalendarDbAdapter(mContext);
mCalendarDbHelper.open();
}
private Runnable r= new Runnable()
{
#Override
public void run()
{
invalidate();
}
};
protected void onDraw (Canvas canvas)
{
String word = "This is a sentence";
paint.setColor(Color.parseColor("#1E90FF"));
paint.setStyle(Style.FILL);
canvas.drawPaint(paint);
paint.setColor(Color.BLACK);
paint.setTextSize(20);
x = this.getWidth()/2;
y = this.getHeight()/2;
canvas.drawText(word, x, y, paint);
}
}
... Now this would be much easier if I could reference the button inside of the custom view, but it doesn't seem I can do that, or if I could simply add to the custom view inside of the main activity class, but it doesn't seem that I can do that either (not without creating a new canvas, which seems to be doing too much for what it is that I want to do (just add the words)). So, finally, is the way I am currently trying to do this a dead end? Any help would be appreciated.
I think I got it. I'll call invalidate with the the AnimatedNegative object defined in my main activity, and then pass in the word from the edit text and a true value, so that I can check for it in the view and redraw. Added code shown below:
Within the main activity:
public void onClick(View arg0)
{
PositiveAnimatedNegative.invalidate();
PositiveAnimatedNegative.add = true;
PositiveAnimatedNegative.positive_word = "This is a positive word";
}
And within the custom view:
if (add == true)
{
canvas.drawText(positive_word, x,y, paint);
}

How to place buttons below my custom view, so user can opt to save what he/she painted?

First of all, thanks in advance for any help you can provide. This has been driving me nuts and google's been no friend of mine for this.
I've created a DrawView so the user can paint something in the app. What I'd like to do is place that DrawView within a layout XML file, so I can place a TextView title on the top and two buttons on the bottom, one of which will save what the user painted as an image file. So far, all I've been able to do is create an area for the user to paint in. Is there any way to place this DrawView view into an XML file? If not, what alternative solutions do I have?
Also, this is an optional question as I'm sure I'll find the solution by googling, at some point, but is there a better way to smoothly draw along the user's finger movement, other than the canvas.drawLine() method I am currently using?
public class Draw extends Activity {
DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
drawView = new DrawView(this);
setContentView(drawView);
drawView.requestFocus();
}
}
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
ArrayList <Float> nikpointx = new ArrayList<Float>();
ArrayList <Float> nikpointy = new ArrayList<Float>();
Bitmap nikbmp;
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
paint.setStrokeWidth(4);
}
#Override
public void onDraw(Canvas canvas) {
//I'm doing this, because the drawCircle method places circles at different points
//in the screen, rather than drawing smooth lines. I haven't found a more elegant
//solution yet :-(
canvas.drawLine(nikpointx.get(i-1), nikpointy.get(i-1), nikpointx.get(i), nikpointy.get(i), paint);
canvas.setBitmap(nikbmp);
}
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
points.add(point);
invalidate();
Log.d(TAG, "point: " + point);
nikpointx.add(event.getX());
nikpointy.add(event.getY());
return true;
}
}
You can place you custom view in the xml layout like this:
<full.package.to.customview.DrawView android:id="#+id/idOfCustom"
//other attributes
/>
You can also add custom attributes to your view to set directly from the xml file.
I don't have any solutions for your second problem.
edit: after a quick search on this site i found this -> Android How to draw a smooth line following your finger

Where to place the AsyncTask() so that i can call it to load image?

Below is my coding where it would load the image when this Activity is called. But i wished to display the progressDialog when it was retrieving the images from the server instead of just a black screen presented to the user. I heard that AsyncTask is able to do but i stuck with where to place the AsyncTask function and calling it.
public class LargeImageScroller extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private static Bitmap bmLargeImage; //bitmap large enough to be scrolled
private static Rect displayRect = null; //rect we display to
private Rect scrollRect = null; //rect we scroll over our bitmap with
private int scrollRectX = 0; //current left location of scroll rect
private int scrollRectY = 0; //current top location of scroll rect
private float scrollByX = 0; //x amount to scroll by
private float scrollByY = 0; //y amount to scroll by
private float startX = 0; //track x from one ACTION_MOVE to the next
private float startY = 0; //track y from one ACTION_MOVE to the next
public SampleView(Context context) {
super(context);
displayRect = new Rect(0, 0, displayWidth, displayHeight);
scrollRect = new Rect(0, 0, displayWidth, displayHeight);
bmLargeImage = Bitmap.createBitmap(1035 , 665, Config.ARGB_8888);
bmLargeImage = createMap(this.getContext());
}
public boolean onTouchEvent(MotionEvent event) {....}
protected void onDraw(Canvas canvas) {....}
private static Bitmap createMap(Context context) {...}
private static Drawable LoadImageFromWebOperations(String url) {....}
private static Bitmap decodeFile(File f, int requiredSize) {...}
}
}
I wish to know where should i place the AsyncTask function so as to display the progressDialog while the program is loading the image from server/cache. Most of the source i found on the internet doesn't say much.
AsyncTask is somehow like a Thread. It is used to handle some time-consuming operations so that the main thread won't be blocked.
In your case, AsyncTask is suitable. However, the place where you would like to put it depends on your logic.
Please read the SDK: AsyncTask to get more info about it. There is also a code snippet that may help you.
Added:
Well, I understand your concern. If you just want to show a progress bar to tell the users that the app is downloading the images from the server. You may handle this way:
1. Create a xml layout file containing a ProgressBar.
2. In OnCreate in Class LargeImageScroller, call setContentView(R.layout.that_layout) to show the progressbar, and Start a AsyncTask to download the images.
3.Inside AsyncTask, override onProgressUpdate(Integer... progress) to tell the ProgressBar the donwloading progress.
4. Inside AsyncTask, override onPostExecute(Long result). This method will be called when the AsyncTask finishes. Here you can do : SampleView sv=new SampleView(this), and then pass the images to the sv object. Then call setContentView(sv) to show your images.
This is just my train of thought. I think you can use AsyncTask in either LargeImageScroller class or SampleView class. Hope ithis comment helps.

Categories

Resources