Originally, I had LinearLayout>ScrollView>TableLayout and the code below:
LinearLayout layout = (LinearLayout) View.inflate(this, R.layout.photos_layout, null);
setContentView(layout);
// TODO Auto-generated method stub
//get the tableLayout which we created in main.xml
tl = (TableLayout)findViewById(R.id.tableLayout1);
for(int i = 0; i < names.length; i++) {
//Create a new row to be added.
TableRow tr = new TableRow(this);
//Create text views to be added to the row.
TextView tv1 = new TextView(this);
TextView tv2 = new TextView(this);
//Put the data into the text view by passing it to a user defined function createView()
createView(tr, tv1, Integer.toString(i+1));
createView(tr, tv2, names[i]);
//Add the new row to our tableLayout tl
tl.addView(tr);
}
The problem is that a scrollView can only have one child, so if I wanted to add more views in addition to the tableLayout I can't. In order to overcome this problem I made the hierarchy like LinearLayout>ScrollView>linearLayout>tableLayout. However, now the code above crashes the app.
What do I need to change in order to populate my table, as well as add views to my newly created linearlayout?
I'd suggest removing the parent LinearLayout. Scrollview in itself can be the parent, and then have one LinearLayout as its only direct child.
In the code you posted that you mentioned was crashing, you're not adding any view to your "newly-created" LinearLayout, instead you're adding a new row to your TableLayout, which if I guess correctly, is inside your scrollview. This is perfectly ok and should not be the cause of the crash.
Related
I have searched and searched on here, but I cant seem to solve this problem. I have a ScrollView, inside the ScrollView is a LinearLayout, I want to read my SQL database and display the results like such;
Linear Layout
ScrollView
Linear Layout
TableRow
TextView
TextView
TableRow
TextView
TextView
/Linear Layout
/ScrollView
/LinearLayout
My code is as follows:
TableRow tRow;
ContextThemeWrapper ttRow = new ContextThemeWrapper(this, R.style.coreTable);
LinearLayout LL = (LinearLayout) findViewById(R.id.linearCores);
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
if (cores.moveToFirst()) {
while (cores.isAfterLast() == false) {
Log.e("CORE LIST", cores.getString(1));
tRow = new TableRow(ttRow);
tRow.setLayoutParams(lp);
tRow.setOrientation(TableRow.VERTICAL);
tRow.setId(cores.getInt(0));
tRow.setBackgroundResource(R.drawable.shape_border);
ContextThemeWrapper newTxtA = new ContextThemeWrapper(this, R.style.coreHeaderView);
TextView tTextA = new TextView(newTxtA);
tTextA.setLayoutParams(lp);
tTextA.setText(cores.getString(1) + " (Lvl " + cores.getString(2) + ")");
tRow.addView(tTextA);
TextView tTextB = new TextView(coreChooser.this);
tTextB.setLayoutParams(lp);
tTextB.setText(cores.getString(5));
tRow.addView(tTextB);
LL.addView(tRow);
cores.moveToNext();
}
}
On my emulator it shows the first tRow.addView, but not the rest, however by background seems to stretch the past the screen.
I am really not sure what I am doing wrong here.
The documentation for TableRow states the following:
A TableRow should always be used as a child of a TableLayout. If a TableRow's parent is not a TableLayout, the TableRow will behave as an horizontal LinearLayout.
If your intention is just to be able to make each pair of TextView share the common background R.drawable.shape_border, then use a nested LinearLayout in place of the TableRow (TableRow is extended from LinearLayout anyway).
Alternatively if there is some specific feature of TableRow you absolutely want to use, then make R.id.linearCores a TableLayout instead of a LinearLayout.
I have created a fragment which should display table of buttons. I used table layout to create a table. But the button table doesn't display in the fragment. What is the problem related to this code and how can I overcome this???
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
ArrayList buttons = new ArrayList();
ScrollView sv = new ScrollView(this.getActivity());
//Set a TableLayout to add buttons
TableLayout tl= new TableLayout(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
tl.setLayoutParams(params);
tl.setOrientation(TableLayout.HORIZONTAL);
for(int i=0;i<5;i++){
TableRow row=new TableRow(this.getActivity());
LayoutParams paramrow = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
row.setLayoutParams(paramrow);
for(int j=0;j<2;j++){
Button button = new Button(getActivity());
button.setText("testing");
button.setPadding(5, 5, 5, 5);
LayoutParams parab = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
button.setLayoutParams(parab);
row.addView(button);
buttons.add(button);
}
tl.addView(row);
}
sv.addView(tl);
}
You're using the wrong type of LayoutParams in at least two places. Views need to use the type of LayoutParams that correspond to their container. Therefore Views contained directly in a TableLayout - i.e., the TableRows - should use TableLayout.LayoutParams. The Views contained in TableRows - the Buttons, in this case - should use TableRow.LayoutParams. And finally, the TableLayout is in a ScrollView, so it should use ScrollView.LayoutParams, which is actually FrameLayout.LayoutParams, since ScrollView extends FrameLayout.
It also appears that you're not adding the ScrollView to the Fragment's View anywhere. I would mention, too, that it might be preferable to define the ScrollView and the TableLayout in layout xml, inflate this layout in onCreateView(), and dynamically create only what needs to be - i.e., the TableRows and Buttons.
I am trying to create a table layout filled with lots of bits of data, the table layout is inside a scroll view.
I am using this to fill it
TableLayout tl;
.....
tl = (TableLayout) findViewById(R.id.layout);
.....
and when I set it I create a new Text View to put into it like so
TextView tv;
....
tr = new TableRow(Context);
.....
tv = new TextView(Context);
tv.setText(progress[1]);
tr.addView(tv);
...
tl.addView(tr);
A new text row is created when I have put 12 text views in it and the tr is added to the tl when it has 12 views in it.
The font size of the text view is default, all I do to the text view you see here
Consider changing to a viewgroup that can recycle/reuse its child views, such as a listview or gridview. That way you won't need to keep everything in memory.
I have one table "TABLE_SUBJECT" which contain a number of subjects. I need to create
one horizontal scroll view with Subject.
How do I create a ScrollView with database items programmatically? If I enter 1o subject then it will be appear in scroll view as a button. Is it possible?
you may create it as below:
ScrollView scroll = new ScrollView(context);
scroll.setBackgroundColor(android.R.color.transparent);
scroll.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
scroll.addView(yourTableView);
if you have many elements first you need to wrap-up and add in the Scroll view; for example i need a many text view inside of scrollview, so you need to create ScrollView->LinearLayout->Many textview
ScrollView scrollView = new ScrollView(context);
scrollView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
TextView textView = new TextView(context);
textView.setText("my text");
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setGravity(Gravity.RIGHT);
linearLayout.addView(textView);
scrollView.addView(linearLayout);
this may help you.
HorizontalScrollView hsrll = (HorizontalScrollView)findViewById(R.id.hrsll);
b = new Button(this);
for (int i = 0; i < 5; i++) {
b.setWidth(LayoutParams.WRAP_CONTENT);
b.setHeight(LayoutParams.WRAP_CONTENT);
b.setText("b"+i);
b.setId(100+i);
hsrll.addView(b);
}
instead of for loop just modify the code as your need(no of records in db). but this the code for creating buttons in dynamically.
I was doing it like this:
Create xml with LinearLayout inside the ScrollView
Create xml as item in ScrollView
In activity set main content as xml with ScrollView
Loop through all table elements with adding new View to LinearLayout form main view
For me works fine.
In Kotlin you can use the below code
val scroll = ScrollView(context)
scroll.setBackgroundColor(R.color.transparent)
scroll.layoutParams = LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT
)
scroll.addView(yourTableView)
Im posting from my phone so please excuse stupid typos and formatting issues.
I have an activity which lists saved games that the player can load.
I created a simple layout xml file which defines a ScrollView. On load, I grab all the saved games and programatically add a view for each saved game to a vertically oriented LinearLayout child of the ScrollView.
The view for each game consists of a Horizontally oriented LinearLayout which in turn contains a Button and a vertically oriented LinearLayout. That LinearLayout in turn contains some TextViews and ImageViews (and one more LinearLayout which I'm ommitting here for the sake of clarity).
The hierarchy looks something like this (some details omitted).
ScrollView
LinearLayout - vertical
Each saved game:
LinearLayout - horizontal
Button - load game
LinearLayout - vertical
TextView - game name
TextView - date string
My problem:
I would like the top of the button and the "game name" texview to be vertically aligned but the TextView (or maybe it's LinearLayout parent) has some rogue padding on top that I can't get rid of. See screenshot for details.
LoadSaved class:
Note: mScrollView is badly named. It refers to the ScrollView's child LinearLayout.
public class LoadSaved extends Activity {
public LinearLayout mScrollView;
private MinerDb mDb;
public void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.loadsaved);
mDb = new MinerDb(this);
mScrollView = (LinearLayout) findViewById(R.id.load_scroll_view);
Bundle[] savedGames = mDb.getSavedGames();
for (int i = 0; i < savedGames.length; i++) {
Bundle game = savedGames[i];
final int gameId = game.getInt("gameId");
String name = game.getString("name");
String date = game.getString("date");
Bundle player = game.getBundle("player");
int playerMoney = player.getInt("money");
int playerHealth = player.getInt("health");
LinearLayout gameContainer = new LinearLayout(getApplicationContext());
gameContainer.setPadding(5, 5, 5, 5);
gameContainer.setGravity(Gravity.TOP);
gameContainer.setOrientation(LinearLayout.HORIZONTAL);
gameContainer.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
Button loadButton = new Button(getApplicationContext());
loadButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
loadButton.setText("Load");
LinearLayout gameInfo = new LinearLayout(getApplicationContext());
gameInfo.setOrientation(LinearLayout.VERTICAL);
gameInfo.setPadding(10,0,10,10);
gameInfo.setGravity(Gravity.TOP);
gameInfo.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
TextView nameView = new TextView(getApplicationContext());
nameView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
nameView.setGravity(Gravity.TOP);
nameView.setText(name);
TextView dateView = new TextView(getApplicationContext());
dateView.setPadding(5,0,0,0);
dateView.setGravity(Gravity.TOP);
dateView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
dateView.setText(date);
LinearLayout playerView = new LinearLayout(getApplicationContext());
playerView.setOrientation(LinearLayout.HORIZONTAL);
playerView.setPadding(5,0,0,0);
playerView.setGravity(Gravity.TOP);
playerView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
TextView playerMoneyView = new TextView(getApplicationContext());
playerMoneyView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
playerMoneyView.setPadding(0,0,10,0);
playerMoneyView.setTextColor(Color.GREEN);
playerMoneyView.setText("$" + playerMoney);
TextView playerHealthView = new TextView(getApplicationContext());
playerHealthView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
playerHealthView.setPadding(0,0,10,0);
playerHealthView.setTextColor(Color.RED);
playerHealthView.setText(playerHealth + "%");
playerView.addView(playerMoneyView);
playerView.addView(playerHealthView);
gameInfo.addView(nameView);
gameInfo.addView(dateView);
gameInfo.addView(playerView);
gameContainer.addView(loadButton);
gameContainer.addView(gameInfo);
mScrollView.addView(gameContainer);
loadButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.e("LoadSaved", "LoadSaved::onCreate: Clicking: " + gameId);
Intent loadGameIntent = new Intent(LoadSaved.this, Miner.class);
loadGameIntent.putExtra("load_game", gameId);
startActivity(loadGameIntent);
finish();
}
});
}
}
}
loadsaved.xml
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/load_scroll_view" />
</ScrollView>
</LinearLayout>
If you want any kind of alignment, why don't you use a RelativeLayout? That's basically designed to align one view with another. android:layout_alignTop sounds like something you want.
(And, of course, verify that the padding values are the same in all controls, but I'm sure you did that.)
Why don't you try using a ListView for that kind of gui.
You will still need to define a row xml.
+1 to the answers suggesting ListView and RelativeLayout. For this type of situation you probably want a ListView with an item layout using RelativeLayout. (ListView will scale much better if there are many items, and if this is for a list of saved games it seems like this could grow quite a bit.) For this type of UI it's recommended to have the whole row/list item clickable rather than use a small Load button, but that's a design issue and ultimately up to you.
Don't use getApplicationContext for creating your views. Activity is a Context, just pass this in your case.
By default LinearLayouts try to align child views by their text baseline if present. Note that the bottom of your button's Load text aligns perfectly with the CURRENT_GAME text in your screenshot. Try gameContainer.setBaselineAligned(false).
Normally your gameInfo layout would only report the baseline of one of its children if you set a baselineAlignedChildIndex, but it looks like this behavior changed between cupcake and eclair when creating LinearLayouts programmatically. (Link to the commit that changed it in AOSP here.)