How to programmatically set a TextView width and height to Wrap Content - android

I am writing a table programmatically from an SQLite database.
In a loop I am generating needed TextViews and am attempting to wrap the data in a TextView called descCol when the data is longer than the existing screen allows.
Suggestions to do this were offered in the following link:
Setting width to wrap_content for TextView through code
However when using either of the suggested methods I'm getting a java.lang.NullPointerException.
Here's my code example:
TextView descCol = new TextView(this);
descCol.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
In this case debug shows it throws a java.lang.NullPointerException on the getLayoutParams() line.
Also I've tried:
TextView descCol = new TextView(this);
ViewGroup.LayoutParams params = descCol.getLayoutParams();
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.width = ViewGroup.LayoutParams.WRAP_CONTENT;
descCol.setLayoutParams(params);
In this case debug shows it throws a java.lang.NullPointerException on the params.height line.
Debug shows that in either case after performing the getLayoutParams() method, params is equal to null, apparently throwing the exception.
I've tried to assign other parameters first to descCol (textcolor, text, gravity etc.) prior to the getLayoutParams() but get the same result.
Suggestions as to how to avoid the java.lang.NullPointerException would be appreciated.

Also I was able to accomplish my task programmatically by simply using the setWidth and setHeight methods.
textview.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
textview.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);

Try this way:
LinearLayout.LayoutParams textParam = new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
textView.setLayoutParams(textParam);

Why are you using getLayoutParams() when you didnt even set the layout Params ?
You need to setLayout Params first. like this.
TextView view = new TextView(this);
view.setText("example textview ");
//adding layout properties
view.setLayoutParams(new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0));
// add the textview to the parentLayout
parentLayout.addView(view);

Related

How to programmatically set Layout to Top and Start of screen?

You can set a LinearLayout to the top left of a screen by doing this:
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
I was wondering how would I do this programmatically?
I have the following piece of code:
LinearLayout btnBar = (LinearLayout) findViewById(R.id.btnBar);
LinearLayout.LayoutParams btnBarParams = new LinearLayout.LayoutParams(screenWidth,screenHeight / 3);
//Not sure how to set the layout to the top left.
but in LayoutParameters there is no addRule() method so I am not sure how to set these attributes. The LinearLayout is inside a RelativeLayout.
EDIT: I think I figured it out, but I am getting a exception. Here is my solution:
LinearLayout btnBar = (LinearLayout) findViewById(R.id.btnBar);
LinearLayout.LayoutParams btnBarParams = new LinearLayout.LayoutParams(screenWidth,screenHeight / 3);
btnBarParams.gravity = Gravity.START;
btnBar.setLayoutParams(btnBarParams);
But I cannot see if this is working because I get a exception on the last line of my solution saying
java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
The solution turned out to be using RelativeLayout.LayoutParams
LinearLayout btnBar = (LinearLayout) findViewById(R.id.btnBar);
RelativeLayout.LayoutParams btnBarParams = new RelativeLayout.LayoutParams(screenWidth,screenHeight / 3);
btnBarParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
btnBarParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
btnBar.setLayoutParams(btnBarParams);
This is how it will work,
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
params.weight = 1.0f;
params.gravity = Gravity.TOP;
btnBar.setLayoutParams(params);

How do I get the `layout_weight` of a TextView?

I have a TableLayout and a row with a couple TextViews. I want to find the layout_weight of the TextView but I cant figure out how. I've tried the following:
TableRow.LayoutParams lp = tv1.getLayoutParams();
and:
ViewGroup.LayoutParams lp = tv1.getLayoutParams();
In the first case I get a type mismatch: "Cannot convert from ViewGroup.LayoutParams to TableRow.LayoutParams", and the second case works fine, however ViewGroup.LayoutParams doesn't have a weight field.
All the different types of LayoutParams are confusing, I'm never sure which to use where.
Try this
TextView text = new TextView(v.getContext());
text.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));
Try this link
You almost had it with your first try. You just need to cast to the correct type:
TableRow.LayoutParams lp = (TableRow.LayoutParams) tv1.getLayoutParams();
Any subclass of LinearLayout.LayoutParams (including TableRow.LayoutParams) will have a weight field.

Dynamically-generated LinearLayouts overlapping

I'm a newbie to Android development, and I'm very much still learning Java too so be gentle!
I am creating an app that can take information about a task (I'm basing it around a sort of homework planner), store that info and then display it in a list. The program must be able to dynamically generate the list from the background files. I have managed all of this so far, but when I create a basic output for each task, containing the "subject" and "details" variables using a LinearLayout they appear on the screen overlapping. They all seem to be creating correctly, but they are all being put in the same place. Are there attributes I can set to make them display in a vertical list???
Here is the piece of code where I generate the viewgroups and display them. This is called from a loop in another part of the program which finds the number of files in internal storage.
TextView subjView;
TextView detailView;
RelativeLayout displayLayout;
LinearLayout taskDisplay = new LinearLayout(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
subjView = new TextView(this);
detailView = new TextView(this);
displayLayout = (RelativeLayout) findViewById(R.id.relative_display_layout);
subjView.setText(subject);
detailView.setText(details);
layoutParams.setMargins(0, 0, 0, 0);
taskDisplay.addView(subjView, layoutParams);
layoutParams.setMargins(10, 0, 0, 0);
taskDisplay.addView(detailView, layoutParams);
displayLayout.addView(taskDisplay);
If I understand correctly, I think your issue is only that you are declaring and then changing the layoutParams margins which sets them both to the same, which is overlapping your TextViews.
Edit
Okay, I am still not 100% sure how you are doing all of this so my example may need to be tweaked. I tried to throw this together quickly so forgive me for any minor mistakes.
New mock up for dynamic layouts:
TextView subjView, detailView;
RelativeLayout displayLayout, rl;
// I am assuming this is your main layout
displayLayout = (RelativeLayout) findViewById(R.id.relative_display_layout);
// Just using a for loop as an example of a loop event, not sure how you are accomplishing this
for(int i = 0; i < data.length(); i++) {
RelativeLayout.LayoutParams rllp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 100);
if (i > 0) {
int rePositionRule = i;
rllp.addRule(RelativeLayout.BELOW, rePositionRule);
}
RelativeLayout taskDisplay = new RelativeLayout(this);
taskDisplay.setLayoutParams(rllp);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(0, 0, 0, 0);
LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams2.setMargins(10, 0, 0, 0);
subjView = new TextView(this);
detailView = new TextView(this);
subjView.setText(subject);
subjView.setLayoutParams(layoutParams);
detailView.setText(details);
detailView.setLayoutParams(layoutParams2);
taskDisplay.addView(subjView);
taskDisplay.addView(detailView);
displayLayout.addView(taskDisplay);
}
Your displayLayout is a relativeLayout.. A relative layout, as the name implies, places element relative to each other. Normally you'd say "element A should go below element B" etc. Since you aren't providing any of these rules for the items you are creating they are just going to all go to the default position in a relative layout (which is the top of the screen.. hence the overlap)
If you don't want to deal with the hassle of changing your code to place things relatively simply switch your displayLayout to a LinearLayout in your xml and code and set its orientation to vertical. You'll probably want to wrap that in a scroll view if it runs off the screen
However, it sounds like what you really want is a ListView...

Setting LayoutParams with few Lines of Code

Is there an easy and simple way to set LayoutParams ? Or to be exactly, the MarginLayoutParams? I want to set the MarginRight to a few dp, unfortunately im not able to set these in the LayoutFile cause the Target is a ListFragment and in Code-Behind looks it very ugly.
The reason i do this not in the Layout of the items is so the code is optimized and perfomant.
To sum up: Is there any very simple and clean way to set Params ?
Yes, you can do something like this:
MyImageView i2 = new MyImageView(context);
LayoutParams lp = new LayoutParams(300, 300);
lp.LeftMargin = 100;
lp.TopMargin = 100;
lp.Gravity = 0;
this.AddView(i2, lp);
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
lp.setMargins( left, top, right, bottom );
You might need to write it as LinearLayout.LayoutParams, depending on what type of layout is the container.
And then you call the method setLayoutParams( lp ); on the given view/layout/widget.

ImageView will not show up

In OnCreate:
svMaster = (ScrollView) findViewById(R.id.scroller); //Only layout in XML file
svMaster.setVerticalFadingEdgeEnabled(false);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
height = display.getHeight();
...
initializeGUI();
svMaster.removeAllViews();
svMaster.addView(llMaster);
In initializeGUI():
llMaster = new LinearLayout(this); //Only direct child of scrollview
LinearLayout llFirstScreen = new LinearLayout(this); //First layout added to llMaster;
//It's size is that of one screen
LinearLayout.LayoutParams lpMaster = new LinearLayout.LayoutParams
(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams lpFirstScreen = new LinearLayout.LayoutParams
(LayoutParams.MATCH_PARENT, height);
llMaster.setLayoutParams(lpMaster);
llMaster.setOrientation(LinearLayout.VERTICAL);
llFirstScreen.setLayoutParams(lpFirstScreen);
llFirstScreen.setBackgroundResource(R.color.blue2);
llFirstScreen.setOrientation(LinearLayout.VERTICAL);
Here's my code pertaining to the ImageView:
ImageView ivWeather = new ImageView(this);
LinearLayout.LayoutParams ivWeatherParams = new LinearLayout.LayoutParams
(Scale(80), Scale(80);
ivWeather.setImageResource(R.drawable.sunny);
Log.d("ImageView loading?", "I hope so");
ivWeather.setScaleType(ScaleType.FIT_XY);
ivWeather.setLayoutParams(ivWeatherParams);
ivWeather.setVisibility(View.VISIBLE); //This is code I tried
ivWeather.setFocusable(true); //when it wouldn't show up
ivWeather.setFocusableInTouchMode(true); //...
ivWeather.invalidate(); //...
...
llFirstScreen.addView(ivWeather);
Log.d("ImageView loading?", "I hope so");
llMaster.addView(llFirstScreen);
...
I have added TextViews with no problem to llFirstScreen, and I am wondering why ImageView
won't show up. I tried even adjusting llFirstScreen's height to WRAP_CONTENT instead of the screen's height. All that did was shrink the layout to the two TextViews. It's as if it never added the ImageView. The Logs I put in check out, so I know the code is running.
Am I missing anything?
Have you tried changing your LinearLayout.LayoutParams from Scale(80), Scale(80) to something like LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT or something? I've never seen Scale(int) used. If that is a custom method can you post it?

Categories

Resources