dynamic xml layout rotation - android

I have two buttons on my main activity and when pressed I want to call the exact same activity exept that on one the layout is rotated 180 degrees. Is there any way to do this (like rotate based on an extra passed from main activity) do I really need to create two different activities with practically the same code in their respective java file?
EDIT: when I say exact same activity I don't mean the same as main. It's just the same for those two buttons...

I think i found a solution for you. Use a custom reverse view as a wraper to reverse the whole layout.
Try to run the sample code below.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int layoutId = R.layout.main;
View content = getLayoutInflater().inflate(layoutId, null);
ReverseView wraper = new ReverseView(this);
wraper.addView(content);
setContentView(wraper);
}
public class ReverseView extends FrameLayout {
public ReverseView(Context context) {
super(context);
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
int px = getWidth() / 2;
int py = getHeight() / 2;
canvas.rotate(180, px, py);
super.dispatchDraw(canvas);
canvas.restore();
}
}
}

You can change the orientation in your activity by adding the following code.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
And you can also create a new layout xml in layout-land/, and when your activity enter the landscape mode, it will try to load the different layout.

Related

How to setContentView to a new class that extends view android

I have two classes, a class called Menu and a class called circleGame. When I run my application the Menu class is started and creates a rectangle on the screen. When the user taps the screen I would like my program to switch to my circleGame class (the circleGame class has the exact same code as my Menu class except it draws a circle rather than a rectangle). I wanted to do this using the Activity.setContentView method, but when I try using that method I get an error saying, "Cannot make a static reference to the non-static setContentView(View) from the type Activity." My code is shown below:
public class Menu extends View{
Paint blue = new Paint(), black = new Paint();
Display display;
//Width of the user's screen.
int screenWidth;
//Height of the user's screen.
int screenHeight;
public Menu(Context context) {
super(context);
blue.setColor(Color.BLUE);
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
display = wm.getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
black.setColor(Color.BLACK);
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//Setting the background color to white.
canvas.drawColor(Color.WHITE);
canvas.drawRect(0, screenHeight/2, screenWidth, screenHeight/1.5f, blue);
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if(event.getAction() == event.ACTION_UP){
circleGame test = new circleGame(getContext());
Activity.setContentView(test);
}
return true;
}
}
My error occurs on the line in the onTouchEvent Listener where I wrote: Activity.setContentView(test); I know I can just put the two codes together to make one large file, but then my code would get two confusing if I just have this one large file later on when I start having a lot of code.
As error states, setContentView is not static method, but rather instance method of Activity. You can only setContentView on some particular activity instance.
If you creating your Menu instance from code of activity, you can pass Activity instance in constructor, and use it later. However it would be better to redesign your code to use Observer Pattern.

create a 16:9 view

I am writing a program that I would like to have a 16:9 screen all the time. I set up a basic linearlayout to host 2 object that I write. The first one overwrite the onMeasure method, so that it'll take a "square" space from the screen, and the second object take the rest. This looks good on a 16:9 device that I have. But when I tried it out on other device, it just looks bad. I tried to extend from the linearlayout that host my object, and overwrite the onMeasure method for the layout. The custom Linearlayout seems to do the 16:9 fine, but my first object (the square), is still getting the big square, not a smaller square confined to the 16:9 strip. Here are the relavent code
MainActivity:
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
layout = new MyLinear(this);
mField = new Field(this);
mField.setId(1);
control = new Controller(this);
control.setId(2);
layout.addView(mField);
layout.addView(control);
registerForContextMenu(control);
setContentView(layout);
mField.requestFocus();
}
the onMeasure code for the custom linearlayout looks like this
public class MyLinear extends LinearLayout{
private int height, width; // dimension of the screen
private Context m_context;
public MyLinear(Context context) {
super(context);
m_context=context;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height_temp = View.MeasureSpec.getSize(heightMeasureSpec);
int width_temp = View.MeasureSpec.getSize(widthMeasureSpec);
double ratio = width_temp/(double)height_temp;
int final_height = (int) (width_temp/1.77);
height=final_height;
if (ratio<1.7) {
setMeasuredDimension(width_temp, (int) (width_temp/1.77));
} else {
setMeasuredDimension(width_temp, height_temp);
}
}
anyone has a better suggestion?
You edit, view.xml file. Add res/layout-xlarge/my_layout.xml folder. after add my_layout.xml file res/layout-xlarge/ folder... I'm sorry for bad english

Getting the width/height of a layout in Android

I'm wondering how to measure the dimensions of a view. In my case it is aan Absolute Layout. I've read the answers concerning those questions but I still don't get it.
This is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);
drawOval();
}
public void drawOval(){ //, int screenWidth, int screenHeight){
AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);
int screenWidth = layoutbase.getWidth();
int screenHeight = layoutbase.getHeight();
Log.i("MyActivity", "screenWidth: " + screenWidth + ", screenHeight: " +screenHeight);
Coordinates c = new Coordinates(BUTTONSIZE,screenWidth,screenHeight);
...some code ...
((ViewGroup) layoutbase ).addView(mybutton, new AbsoluteLayout.LayoutParams(BUTTONSIZE, BUTTONSIZE, c.mX, c.mY));
mybutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showText(mybutton);
}
});
}
public void showText(View button){
int x = findViewById(LAYOUT).getWidth();
int y = findViewById(LAYOUT).getHeight();
Toast message = Toast.makeText(this, "x: " + x , Toast.LENGTH_SHORT);
message.show();
}
The getWidth() command works great in showText() but it does not in drawOval(). I know it looks a bit different there but I also used the int x = findViewById(LAYOUT).getWidth(); version in drawOval(), and x/y are always 0. I don't really understand why there seems to be no width/height at that earlier point. Even if I actually draw a Button on the Absolute Layout, getWidth() returns 0. Oviously I want to measure the sizes in drawOval().
I think will help you.
LinearLayout headerLayout = (LinearLayout)findviewbyid(R.id.headerLayout);
ViewTreeObserver observer = headerLayout .getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
int headerLayoutHeight= headerLayout.getHeight();
int headerLayoutWidth = headerLayout.getWidth();
headerLayout .getViewTreeObserver().removeGlobalOnLayoutListener(
this);
}
});
}
getWidth() is giving you 0 because onCreate is called before layout actually happens. Due to views being able to have dynamic positions and sizes based on attributes or other elements (fill_parent for example) there's not a fixed size for any given view or layout. At runtime there is a point in time (actually it can happen repeatedly depending on many factors) where everything is actually measured and laid out. If you really need the height and width, you'll have to get them later as you've discovered.
This specially deal with Dimensions so
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
This may help you in managing dimensions.
Note: This returns the display dimensions in pixels - as expected. But the getWidth() and getHeight() methods are deprecated. Instead you can use:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
as also Martin Koubek suggested.
If your goal is to simply draw an oval on the screen, then consider creating your own custom View rather than messing around with AbsoluteLayout. Your custom View must override onDraw(android.graphics.Canvas), which will be called when the view should render its content.
Here is some extremely simple sample code that might help get you started:
public class MainActivity extends Activity {
private final Paint mPaint = new Paint();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
// create a nested custom view class that can draw an oval. if the
// "SampleView" is not specific to the Activity, put the class in
// a new file called "SampleView.java" and make the class public
// and non-static so that other Activities can use it.
private static class SampleView extends View {
public SampleView(Context context) {
super(context);
setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN);
// smoothen edges
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(4.5f);
// set alpha value (opacity)
mPaint.setAlpha(0x80);
// draw oval on canvas
canvas.drawOval(new RectF(50, 50, 20, 40), mPaint);
}
}
}
This give you screen resolution:
WindowManager wm = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point outSize = new Point();
display.getSize(outSize);
kabuko's answer is correct, but could be a little more clear, so let me clarify.
getWidth() and getHeight() are (correctly) giving you 0 because they have not been drawn in the layout when you call them. try calling the two methods on the button after addView() (after the view has been drawn and is present in the layout) and see if that gives you the expected result.
See this post for more information.

How to add view components dynamically from activity

I am attempting to create a user interface dynamically. I have successfully create a view and loaded my background image. I have created two additional small view items to display on the background. My problem is that I have not been able to find any advice/instruction that tells me how to draw the small views. It seems that it should be a trivial exercise and I am guessing it is just finding the correct referencing. Hope someone out there can point me in the right direction.
Here is my Activity:
public class GhostActivity extends Activity implements OnTouchListener
{
private DrawView ghostView;
public Card mCard1, mCard2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// ToDo add your GUI initialization code here
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ghostView = new DrawView(this);
setContentView(ghostView);
//get the window size
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Context context = getApplicationContext();
//create view items with initial positions
Point startPoint;
startPoint = new Point();
startPoint.x = 5;
startPoint.y = 3;
mCard1 = new Card(context, 1, R.drawable.bol_geel, startPoint);
startPoint.x = 5;
startPoint.y = 43;
mCard2 = new Card(context, 2, R.drawable.bol_rood, startPoint);
//now display them on the ghostView *****************HOW?
// set the callbacks
ghostView.setOnTouchListener(this);
mCard1.setOnTouchListener(this);
mCard2.setOnTouchListener(this);
}
and here is the View;
public class DrawView extends View
{
Drawable bg ;
public DrawView(Context context) {
super(context);
//setFocusable(true);
Drawable bg = this.getResources().getDrawable(R.drawable.bubbleblue480x800);
setBackgroundDrawable(bg);
}
#Override protected void onDraw(Canvas canvas) {
// canvas.drawColor(0x0000000); //if you want another background color
//draw on the canvas
}
}
edit: I believe my problem is needing to pass a pointer to the ghostView canvas. what makes me think that is if I create the children within ghostView then call their .draw method they appear exactly as I would expect.
#Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0x0000000); //if you want another background color
//draw the cards on the canvas
mCard1.draw(canvas);
mCard2.draw(canvas);
}
so at this point I am wondering how to get a reference pointer to the ghostView canvas.
To be honest I am finding the whole Activity - View relationship confusing.
Edit: I have taken a different approach based on detail in this tutorial
http://www.kellbot.com/2009/06/android-hello-circle/
It uses a FrameLayout and it seems I can achieve my objective.
To add view dynamically to view your class must extends from ViewGroup or LinearLayout class then you will able to call method addView.
Inside your ghost view first add a layout e.g Linear or Relative. Then only you could able to add views inside that layout you cant simply add a view to a xml file.
Or you can create a dynamic layout then only u can add view inside that layout.
RelativeLayout relative= new RelativeLayout(findViewById(R.id.your relativeLayoutID));
relative.addView(child);
child could be anything button textview and widget.

How to draw a dynamic drawing over a layout

I am trying to make a thermometer. For this I have an image of a thermometer(a png file) which i have inserted
into the layout using ImageView. Now I want to draw a line over this image to show the effect of temperature reading.
Here is my code.
main.xml
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
</ImageView>
<com.focusone.Android.DrawExample.CustomDrawableView
android:id="#+id/custom_drawable_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
height='100'
/>
</AbsoluteLayout>
DrawExample.java
package com.focusone.Android.DrawExample;
public class DrawExample extends Activity {
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
CustomDrawableView.java
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context v,AttributeSet as){
super(v,as);
drawShape(as);
}
public void drawShape(AttributeSet ast) {
int x =45; int y=15 ; int width=5; int height=0 ;
height= Integer.parseInt(ast.getAttributeValue(null, "height"));
mDrawable = new ShapeDrawable(new RectShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
Now I can draw a line on top of the thermometer image using this program.
But how do i change the height of line during runtime.
Since height=100 is written in the xml file I don't know how I can change it.
Please somebody help me.
First I think you don't need to pass attributes in drawShape(AttributeSet ast) but just height in your constructor CustomDrawableView(). Then as Chris said you should have another method in the custom view like
public void setTemperature(int tmp){
drawShape(tmp);
invalidate(); //this will call onDraw()
}
In your main activity make a reference to your custom view so you can call its public methods
CustomDrawableView temperatureView =
(CustomDrawableView) findViewById(R.id.custom_drawable_view);
temperatureView.setTemperature(50);
You can:
Make "height" a member of your CustomDrawableView
Then create a method setHeight(int height) where you change the value of height.
Then in your activity use (CustomDrawableView)findViewById(R.id.custom_drawable_view) to get a reference to your viewObject.
Then change the value as you like with calling setHeight(x)
hope that helps

Categories

Resources