create layout through code - android

I created layout through code so that i can add multiple views on that layout using code below.
public class AndroidPrepChart extends Activity {
GraphicalView gView;
GraphicalView gView2;
GraphicalView gView3;
BarChart barChart = new BarChart();
BarChart2 barChart2 = new BarChart2();
BarChart3 barChart3 = new BarChart3();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gView = barChart.execute2(this);
gView2 = barChart2.execute2(this);
gView3 = barChart3.execute2(this);
LinearLayout layout = new LinearLayout(this);
layout.addView(gView, 150, 200);
layout.addView(gView2, 150, 200);
layout.addView(gView3, 150, 150);
setContentView(layout);
}
}
Here output screen contains three charts but i want to position third chart in the second line. Please help me to solve this problem. I am beginner in Android.

You can achieve this by nesting multiple LinearLayouts and changing the orientation property
in XML this would look something like this (showing only the relevant elements and attributes):
<LinearLayout android:orientation="vertical">
<LinearLayout android:orientation="horizontal">
<!-- Your first 2 graphs go in this LinearLayour -->
</LinearLayout>
<LinearLayout android:orientation="horizontal">
<!-- The third graph goes in here -->
</LinearLayout>
</LinearLayout>
You can programmatically manipulate the orientation of the LinearLayout by using the setOrientation method. E.g:
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

Are you completely sure that you can't do it with an XML? Coding gui from the code is quite more difficult.
In relation to your question:
I guess you want the third GraphicalView to be to the right of the second one.
Two ways to do it:
Using a RelativeLayout or using a second LinearLayout.
Example:
LinearLayout layout = new LinearLayout(this);
layout.addView(gView, 150, 200);
LinearLayout two = new LinearLayout(this);
two.setOrientation(LinearLayout.VERTICAL);
two.addView(gView2, 150, 200);
two.addView(gView3, 150, 150);
layout.addView(two);
Try not using that way of giving size to a View, you should use setLayoutParams.
For instance your layout should have something like:
layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

Related

Semi transparent Instruction activity in android

I want to display instruction activity when user opens the app for the first time. I am using shared preference for that. Whatever I am doing so far is working. But I think my way of achieving this is not right.
What I am following:
I am drawing a transparent instruction image(with instructions) in photoshop.
Checking if user is opening that page for the first time(using shared preference).
Displaying that particular image in an activity with translucent theme
private void showFrontPageGuideIfFirstTime(){
if(!prefKeeper.getBoolean(PreferenceKey.FRONT_GUIDE)){
Intent intent = new Intent(this, ShowGuide.class);
intent.putExtra(BACKGROUND_KEY, R.drawable.front_page_png);
this.startActivity(intent);
prefKeeper.putBoolean(PreferenceKey.FRONT_GUIDE, true);
}
}
And my instruction page looks something like(made in photoshop):
The Instruction Image
But I think by this way it would not work in all smart phone screens.
Where am I wrong, and what would be the best way of doing this?
Implementation as below
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/framelayout"
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="in.excogitation.example_mvptdd.MainActivity">
<!-- Include your layout here-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"/>
</FrameLayout>
In your activity.java
public class MainActivity extends AppCompatActivity {
FrameLayout frameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Parent FrameLayout
frameLayout = (FrameLayout) findViewById(R.id.framelayout);
// Dynamically create a relativelayout which will be appended to framelayout
final RelativeLayout relativeLayout = new RelativeLayout(getApplicationContext());
relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams
.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
relativeLayout.setBackgroundColor(Color.DKGRAY);
relativeLayout.setAlpha(0.7f);
relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// remove the whole relativelayout on click
frameLayout.removeView(relativeLayout);
}
});
RelativeLayout.LayoutParams params;
// Place 1st 30x40 ImageView at (50,60) coordinates
params = new RelativeLayout.LayoutParams(100, 100);
params.leftMargin = 20;
params.topMargin = 50;
final ImageView imageView1 = new ImageView(getApplicationContext());
imageView1.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_star));
// Add 1st imageview to relative layout
relativeLayout.addView(imageView1, params);
// Place 2nd 30x40 ImageView at (100,60) coordinates
params = new RelativeLayout.LayoutParams(120, 120);
params.leftMargin = 800;
params.topMargin = 450;
final ImageView imageView2 = new ImageView(getApplicationContext());
imageView2.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_star));
// Add 2nd imageview to relative layout
relativeLayout.addView(imageView2, params);
// finally add it ot the framelayout
frameLayout.addView(relativeLayout);
}
}
Ofcourse you should modify this code with your own images and colors and interactions. Its just a simple working version that is better than loading a whole image upfront when you all you want is smaller helper images on a translucent background for the instructions.
Also you in this way you make things more Android-ish and editable. You can add more children to the relative layout like a textview to include instructions.
Screenshot on load of app and hence the relative layout as an overlay.
Screenshot on click/touch , the relative layout is removed.

How to add Buttons dynamically into ScrollView

I'm having a difficulty adding buttons dynamically to a ScrollView. The code below is adding the buttons BUT there is no scroller.
If I'm putting the buttons directly in the XML (not dynamically) it's working and I can scroll down/up.
My view:
<ScrollView android:id="#+id/ScrollView01"
android:layout_width="264dp"
android:layout_height="match_parent"
android:fillViewport="true"
>
<LinearLayout
android:id="#+id/buttons"
android:layout_width="264dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:scrollbars="vertical"
>
** HERE THE BUTTONS SHOULD BE ADDED DYNAMICALLY **
</LinearLayout>
</ScrollView>
The code which adding buttons:
// create new button
final Button newbutton = new Button(this);
// set background color
newbutton.setBackgroundColor(Color.GRAY);
// set width and height
newbutton.setWidth(50);
newbutton.setHeight(20);
// set position
newbutton.setY(((float)numOfButton*20)+20);
newbutton.setX(100);
// set text
newbutton.setText(Integer.toString(numOfButton));
// create patameter
final LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT
);
//set listener
android.view.View.OnClickListener buttonListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// make all the DrawView invisible
for(View view : comments){
view.setVisibility(View.INVISIBLE);
}
// set the chosen comment visible
comments.get(numOfButton).setVisibility(View.VISIBLE);
boardsHandler.setCurrenBoard(numOfButton);
}};
newbutton.setOnClickListener(buttonListener);
// creating a thread to add button
buttons.post(new Runnable() {
#Override
public void run() {
buttons.addView(newbutton, p);
}
});
Is it something with the LinearLayout.LayoutParams p ?
Thanks!
Try following code
first do
LinearLayout myContainer = findViewById(R.id.layoutId);
When you set parameters for a view, they need to correspond to the parent view for your widget.
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT);
finally add button as you are doing.
try and tell if it works
Setting X and Y position will not work. The LinearLayout layouts it's children vertically or horizontally, only taking their width/height into account.
Besides this -- have you tried calling buttons.invalidate() after buttons.addView(...). This should refresh the layout and should show your newbutton.
This is a rather old post but I found it quickly when doing research on that kind of problem. So I'll post am answer anyway, maybe it'll be of help to anyone..
I had a similar problem with a relative layout to which buttons were added dynamically. I found a workaround in defining the layout's size manually when adding the buttons. For your case, adding the line
buttons.getLayoutParams().height = numOfButton*20+40;
after
buttons.addView(newbutton, p);
might help, though it's probably not the best solution.
I thought my mistake was using the RelativeLayout at all, but since you appear to have the same problem...
Ever thought of using a table layout?

Nesting layouts and dynamically updating them

I want to nest a TableLayout inside a RelativeLayout and later dynamically edit the TableLayout in my Java Code.
My XML-File looks like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_load_date"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LoadDateActivity" >
<!-- few buttons and textviews -->
<TableLayout
android:id="#+id/activity_load_date_table_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/button" >
</TableLayout>
</RelativeLayout>
Java Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_date);
//Do something with my Buttons and TextViews(this works fine)
tblLayout = (TableLayout) findViewById(R.id.activity_load_date_table_layout);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.button_calc) {
for (int i = 0; i < listOfEntries.size(); i++) {
Entry temp = listOfEntries.get(i);
if (temp.getDate().getTime() >= startDate.getTime()
&& temp.getDate().getTime() <= endDate.getTime()) {
TableRow tr = new TableRow(this);
TextView comm = new TextView(this);
comm.setText(listOfEntries.get(i).getComment());
TextView val = new TextView(this);
val.setText(String.valueOf(listOfEntries.get(i).getValue()));
LayoutParams params = new LayoutParams(0,
LayoutParams.WRAP_CONTENT, 1f);
tr.setLayoutParams(params);
tr.addView(comm);
tr.addView(val);
tblLayout.addView(tr);
}
}
tblLayout.invalidate(); //Shouldn't this redraw the entire TableLayout and therefore adding my TableRows? This is not working.
}
}
Through various tests with TextViews and Toasts I have gathered that the tblLayout should be filled and the TableRows are added to the Layout, the only thing that is not working is the "repainting" of my Layout. How do I achieve that?
Edit:
Apparently the thing that made this not work was actually the LayoutParams given to the TableRow, once I commented those out I atleast got it printed to the screen. They are however not where I expect them to be.
I expected them to be below the buttons, instead they are in the top left corner on top of the buttons. This leads me to believe that the TableLayout is actually the same size as the RelativeLayout but is layered above the RelativeLayout. The error should therefor lie in my XML-File. What height do I need to give my TableLayout to make this work the way I expect?
Edit2:
I needed to add the android:layout_below attribute to my TableLayout, works as a charm now!
You need to call the method "requestLayout()"
Call this when something has changed which has invalidated the layout of this view. This will schedule a layout pass of the view tree.

adding views dynamically

I am using the following layout and want to add textviews one below another dynamically(depending on the data I want to display)
main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/contain"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
</ScrollView>
So I tried this
public class Feeds extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent=getIntent();
Bundle b=intent.getExtras();
String s= b.getString("datapack");
Log.w("String",s);
String data[]=s.split("#");
String temp="";
LinearLayout l=(LinearLayout)findViewById(R.id.contain);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
(LayoutParams.WRAP_CONTENT), (LayoutParams.WRAP_CONTENT));
RelativeLayout relative = new RelativeLayout(getApplicationContext());
relative.setLayoutParams(lp);
for(int i=1;i<data.length;i++)
{Log.w("i data",data[i]);
temp=temp + data[i] + ",";
Log.w("tag",temp);
if(i%5==0)
{Log.w("data",temp);
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(lp);
tv.setId(i);
tv.setText(temp);
relative.addView(tv, lp);
temp=null;
}
}
l.addView(relative);
}
}
I am using Scrollview for the first time so that is crating a bit of problem but the main problem is that the textviews in the relative layout overlap one another.How can I specify the gap between each view??
If you're adding views into a RelativeLayout you have to set where the view will be placed, different than LinearLayout that you only need to add the views inside there.
Trye to change to this
LinearLayout layout= new LinearLayout (getApplicationContext());
layout.setLayoutParams(lp);
And here you go a little tip. Do not do this
if(i%5==0)
{Log.w("data",temp);
try to do this
if(i%5==0){
Log.w("data",temp);
it's better to read and understand
I don't see where you are defining the positions for each textview, ie layout_below, layout_toLeftOf... If no positions are defined the relative layout stacks each view in the upper left corner.
Addition
It seems digulino and I agree. I would like to add that you should be able to get the layout scheme you want with only a RelativeLayout inside a ScrollView, maybe a HorizontalScrollView too if you want horizontal scrolling with fling gesture support.

Custom view: nested linearlayout not showing up

I created a custom view. In it, theres a line, a textview, another line. beneath the bottom line, i wanted to put a new horizontally oriented linearlayout. when i run it, this nested linearlayout doesnt seem to show up at all. Instead, i can see the test button right underneath the bottom line. what am i doing wrong?
public class MyView extends LinearLayout {
public MyView(Context context, Question question) {
super(context);
// this.setLayoutParams(params);
this.setOrientation(VERTICAL);
this.setBackgroundColor(Color.WHITE);
LinearLayout.LayoutParams lineParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, 2);
View topLine = new View(context);
lineParams.setMargins(0, 15, 0, 0);
topLine.setBackgroundColor(Color.argb(255, 0, 159, 218));
topLine.setLayoutParams(lineParams);
this.addView(topLine);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
//Challenge Question
TextView questionText = new TextView(context);
questionText.setTextColor(Color.BLACK);
questionText.setTextSize(14);
questionText.setLayoutParams(params);
questionText.setGravity(Gravity.CENTER_HORIZONTAL);
questionText.setText(question.getQuestion());
this.addView(questionText);
View bottomLine = new View(context);
bottomLine.setBackgroundColor(Color.argb(255, 0, 159, 218));
bottomLine.setLayoutParams(lineParams);
this.addView(bottomLine);
LinearLayout innerLayout = new LinearLayout(context);
LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(300, LayoutParams.WRAP_CONTENT);
innerLayout.setLayoutParams(innerLayoutParams);
innerLayout.setBackgroundColor(Color.RED);
innerLayout.setOrientation(HORIZONTAL);
//TableLayout for the multiple choices
TableLayout tableLayout = new TableLayout(context);
LayoutParams tableLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// tableLayoutParams.weight = .8f;
tableLayout.setBackgroundColor(Color.RED);
tableLayout.setLayoutParams(tableLayoutParams);
innerLayout.addView(tableLayout);
this.addView(innerLayout);
Button button = new Button(context);
button.setLayoutParams(params);
button.setText("testing 123");
this.addView(button);
}
Note that I pasted the code without all the stuff that I added to the tablelayout. I probably should have pasted that too. But it didn't work when I did that either. but either way, if i set the nested linearlayout to 300 width and set a background color of red to it, i should at least see it, no?
Think about what the height of the inner layout should be. Right now it is wrap_content and contains a TableLayout (with no rows) with its height also set to wrap_content. There doesn't seem to be anything in that inner layout giving it a height dimension, so that may be why it is not being displayed.
Trying the following will make your layout visible:
LinearLayout.LayoutParams innerLayoutParams = new LinearLayout.LayoutParams(300, 300);
More usefully, you can try adding something with a real width/height to the TableLayout.
Also consider writing your layout in XML to better separate your application logic and the presentation.

Categories

Resources