creating a xml layout from a custom layout. is it possible? - android

MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle(R.string.app_name);
setContentView(new SampleView(this));
}
}
SampleView.java:
public class SampleView extends View {
#Override
protected void onDraw(Canvas canvas) {
if (certaincondition = true) {
//add elements to canvas etc
} else {
//How do I do the below? The layout is defined in xml.
//I do not want to use Intent. Please help me
//create a layout from resource R.layout.idAbout and transfer control.
}
}
}

Use a layout inflater:
View newRootViewElement;
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
newRootViewElement= li.inflate(R.layout.idAbout, null);

You can inflate a layout using
View.inflate(getContext(), R.layout.idAbout, viewParent);
where viewParent is a ViewParent that will be the parent of the inflated view (and can be null).
But what are you trying to do? It's more than a little odd to start a new activity or to modify the view hierarchy from within onDraw(). You might want to post a runnable to a Handler that will do what you want on the next cycle of the event loop. To start a new activity (such as displaying “About” info for the app) you should take a look at the Intent class.

Related

How to inflate a costum-view on a view

I got an custom class. Which works great.
public class FocusGameView extends SurfaceView implements Runnable
At the activity itself I want to put the 'FocusGameView' on a view that I already created on the xml file.
so I tried to use the 'inflate' like this:
public class FocusGame extends Activity {
FocusGameView fgv;
View v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fgv= new FocusGameView(this);
v=(View) findViewById(R.id.frame_focus_game);
LayoutInflater mInflater;
mInflater = LayoutInflater.from(fgv.getContext());
v = mInflater.inflate(R.layout.activity_focus_game, null);
setContentView(R.layout.activity_focus_game);
}
The result of this code is opening the activity and set the layout. without put the custom view on the view itself.
I really hope you could help me with that.
Thanks in advance;
Yaniv.
You can only add a view to a view group, not a view, so lets image your View v is a RelativeLayout:
public class FocusGame extends Activity {
FocusGameView fgv;
RelativeLayout v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_focus_game);
v=(View)findViewById(R.id.frame_focus_game);
fgv= new FocusGameView(this);
v.addView(fgv); //You only need to add the view to a parent to make it appear
}

How to change frame layout background and text in other method, which we have added in ocreate() method of the same activity class?

/**How to change frame layout background and text in other method onclick listener, which we have added in ocreate() method of the same activity class? */
public class MainActivity extends Acitvity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.mainView); **//Main view**
final FrameLayout rootLayout = (FrameLayout)findViewById (R.id.mainViewRootLayout);
FrameLayout ribbonLayout = (FrameLayout)findViewById(R.id.mainribbonLayout);
TextView ribbonText = (TextView)findViewById(R.id.mainribbonLayoutText);
ribbonText.setText("MainRibbonViewBeforeClick");
LayoutInflater inflater = (LayoutInflater)getSystemService (context.Layout_Inflater_service);
addRow(rootLayout);
}
}
/*Here is the calling method in same class which adds one more text view, if we click on text view the ribbon text of oncreate method has to be changed*/
public void addRow(FrameLayout rootLayout)
{
Rect rect = new Rect();
rootLayout.getDrawingRect(rect);
FrameLayout ribbonLayout = (FrameLayout)findViewById(R.id.subRibbonLayout);
TextView subText = (TextView)findViewById(R.id.subribbonLayoutText);
subText.setText("ClicktoChangeTheRibbon");
subText.setOnclickListener(new onClickListener() **//Setting up the listener
{
public vid onclick(View v){
FrameLayout ribbonLayout = (FrameLayout)findViewById(R.id.mainribbonLayout);
TextView ribbonText = (TextView)findViewById(R.id.mainribbonLayoutText);
ribbonText.setText("SubRibbonAfterClick");
/*Here I need to implement a code that changes the ribbon text which I have added in onCreate method*/
}
});
You should create
FrameLayout ribbonLayout
TextView ribbonText
above the public void onCreate(Bundle savedInstanceState) line.
It will create variable lifetime for whole activity. SO in activity anywhere you will able to access it.
Currently your created objects are available only for onCreate method.

Which lifecycle method will be invoked when Activity is showing?

Sometimes I need to do some operations(e.g. changing layout) when the activity is just showing. What I do now is using post():
public class MyActivity extends Activity {
#Override
public void onCreate() {
...
container.post(new Runnable(){
resize(container);
});
}
}
Is there any lifecycle method like onCreate can be used to simplify the code, that I don't need to call post?
#Override
public void onX() {
resize(container);
}
I think you mean do something after the UI is displayed.
Using a global layout listener has always worked well for me. It has the advantage of being able to remeasure things if the layout is changed, e.g. if something is set to View.GONE or child views are added/removed.
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null);
// set a global layout listener which will be called when the layout pass is completed and the view is drawn
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
// at this point, the UI is fully displayed
}
}
);
setContentView(mainLayout);
http://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener.html

Android: Load Layout-File dynamically

I have a question about Android.
Assume we have our main xml layout file, and defining there a place holder by using (for example) a FrameLayout. Also assume we have 2 other xml layout files displaying any content.
So what I want to do is inject dynamically and programmtically one of the two layouts into the place holder. I know there exists the concept of Activitis, Fragments, ViewFlipper etc. But I find it comfortable to do things like this:
public class MainActivity extends Activity {
private FrameLayout placeHolder;
private View view1;
private View view2;
private RelativeLayout canvasPlaceHolder;
private PuzzleCanvas canvas;
private TextView infoLabel;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init gui
setContentView(R.layout.activity_main);
// Load layouts from xml
LayoutInflater factory = getLayoutInflater();
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
}
}
with for example a Button on screen that does something like this:
#Override
public void onClick(View v) {
placeHolder.removeView(view1);
placeHolder.addView(view2);
}
For example to show a loadingAnimation (view2) instead of the normal content (view1) and so I can define both views comfortable and independent in xml.
Is the use of LayoutInflater commendable? What about the performance and memory management? What do you think about this? Is that a common way in Android?
Use 'include ' tag on the xml's frame layout to include both your xml's in the main xml. All you have to do is switch their ' VISIBILITY' through java according to ur app logic.
eg: on a listener, set :
public void onClick(View v) {
innerView1.setVisibilty(View.INVISIBLE);
innerView2. setVisibilty(View.VISIBLE);
}
// Load layouts from xml
LayoutInflater factory = getLayoutInflater();
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
Using LayoutInflater is ok, but I suggest not directly do this action in onCreate, if your layout is very complex, it might cause ANR (draw layout over 5 secs). Since these two views only appears after user reaction, I prefer to do with sendEmptyMessage with handler.
onCreate(...){
handler.sendEmptyMessage(1);
}
private Handler handler = new Handler(){
#Override
public void handleMessage(final Message msgs) {
if(msgs.what == 1){
view1 = factory.inflate(R.layout.view1, null);
view2 = factory.inflate(R.layout.view2, null);
}
}
}

OnTouchListener on Activity never calls

I used this code, but when i click on activity at runtime, it never hits in OnTouch() method. Can someone guide me what i am doing wrong? Should i need to setcontentview of this activity? Actually i want the coordinates of activity where user touch during execution.
public class TouchTestAppActivity extends Activity implements OnTouchListener
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.touch);
}
#Override
public boolean onTouch(View arg0, MotionEvent arg1)
{
// TODO Auto-generated method stub
String test = "hello";
}
}
UPDATE:
You need to do this :
In your XML layout file, you need an ID for the root view: android:id="#+id/myView"
In youer onCreate() method, write this:
LinearView v= (LinearView) findViewById(R.id.myView);
v.setOnTouchListener(this);
Assuming that your root view is a LinearView
You should the onTouchListener to relevant GUI components.
For example:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.touch);
TextView someView = (TextView)findViewById(R.id.some_view_from_layout_xml);
someView.setOnTouchListener(this); // "this" is the activity which is also OnTouchListener
}
You have to add a the listener using setOnTouchListener() otherwise who will give call to your onTouch method. any listener works on any view. so you have to add the listener to the view eg button.setOnTouchListener(this);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View vi = inflater.inflate(R.layout.yourxml, null);
setCOntentView(vi);
vi.setOnTouchListener(this);
In onCreate, you need to set the content view (just uncommenting the second line should probably work) and then you need to set your OnTouchListener (your activity) as the onTouchListener for a view in your application.
Let's say you've got a view in your layout called "MainView"; it would look something like this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View view = findViewById(R.id.MainView);
view.setOnTouchListener(this);
}
This article has a good example:
http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-2-building-the-touch-example/1763

Categories

Resources