Dynamic Textview scrollbar not showing - android

I have created a textview dynamically and want to make it scrollable.
final RelativeLayout.LayoutParams params = parseLayoutParams(
frameMargins, context);
tv.setText(Utility.getpropertyString(controls.getText()));
final String textColor = Utility.getpropertyString(controls.getTextcolor());
tv.setTextColor(Color.parseColor(textColor));
tv.setTextSize(12);
tv.setGravity(Gravity.CENTER_VERTICAL);
tv.setTextSize(tSize);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setMaxLines(controls.getMaxlines());
tv.setTag(controls.getTagId());
tv.setLayoutParams(params);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setVisibility(controls.getVisibility());
tv.setVerticalScrollBarEnabled(isScrollable);
tv.setScroller(new Scroller(context));
tv.setMovementMethod(new ScrollingMovementMethod());
tv.setScrollBarFadeDuration(0);
But I am not able to see scrollbar in the textview niether when not scrolling nor when we scroll it. Please help!

From Api 21, the View scrollbar visibility is only reserved for xml layouts because an important function called initializaScrollBars was removed due to an issue while passing TypeArray variable as a parameter.
So, to accomplish what you need programmatically, you can do it like this
Create an xml layout called scrolltextview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
Now, to create it programmatically
TextView tv = (TextView) LayoutInflater.from(this).inflate(R.layout.scrolltextview, null, false);
// now decorate it as your needs
tv.setText(m);
tv.setTextColor(Color.BLUE);
tv.setTextSize(23);
...
tv.setMovementMethod(new ScrollingMovementMethod());
// this is needed only if you want to show scrollbar also when text is not scrolling
tv.setScrollBarFadeDuration(0);
// thecontainer = the layout you want to add your new textview
thecontainer.addView(tv);

As Ferran noted, initializeScrollBars() has been removed. See here for the bug report and the rationale for its removal. As far as I can tell, there is no other strictly programmatic way to specify scollbars for a view. All paths go through XML. :-(
I think that Ferran's answer is a good way to go: it works, is easy to understand and should be easy to document. There are, however, other ways to programatically create a TextView with scrollbars with a slight assist from styles.
For API 21 and above
Define a style called "ViewWithScrollBars" as follows:
<style name="ViewWithScrollbars">
<item name="android:scrollbars">vertical</item>
</style>
We can now use the four-argument constructor for TextView to apply the style.
TextView tv = new TextView(this, null, 0, R.style.ViewWithScrollbars);
This method will create a TextView with scrollbars. There is at least one caveat however. When a TextView is created with a single argument
new TextView(Context)
The constructor telescopes through other constructors that add additional arguments. One of these constructors is defined as follows:
public TextView(Context context, #Nullable AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.textViewStyle);
}
The third argument com.android.internal.R.attr.textViewStyle is an Android internal style that will pick up a default textViewStyle from the theme. The call I suggest uses zero for the third argument, so any textViewStyle defined in the theme will not be applied.
A reasonable fix for this might be to do the following:
tv = new TextView(this, null, android.R.attr.textViewStyle, R.style.ViewWithScrollbars);
Unfortunately, if the third argument (defStyleAttr) is defined in the theme, then the fourth argument (defStyleRes) is not used. As a result, the scrollbars will not appear.
If you use textViewStyle then you will have to make adjustments or just use the following approach.
For all APIs
Using the style "ViewWithScrollBars" from above, we can define a ContextThemeWrapper that will install scrollbars into the theme that will be used to create the TextView.
ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.ViewWithScrollbars); // "this" is the Activity
tv = new TextView(ctw);
I refer you to an article by Chris Banes entitled "Theme vs Style" that explains how theme overlays work.
The following puts all this together.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = new TextView(this);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// This will actually work for API 21 and above.
ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.ViewWithScrollbars);
tv = new TextView(ctw);
} else {
tv = new TextView(this, null, 0, R.style.ViewWithScrollbars);
}
tv.setText(R.string.lorem);
tv.setTextColor(Color.parseColor("red"));
tv.setTextSize(12);
tv.setGravity(Gravity.CENTER_VERTICAL);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 24);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setMaxLines(7);
tv.setTag(View.generateViewId());
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(params);
tv.setEllipsize(TextUtils.TruncateAt.END);
tv.setVisibility(View.VISIBLE);
tv.setVerticalScrollBarEnabled(true);
tv.setScroller(new Scroller(this));
tv.setMovementMethod(new ScrollingMovementMethod());
tv.setScrollBarFadeDuration(0);
((RelativeLayout) findViewById(R.id.layout)).addView(tv);
}
}

Related

Inflate into "this"?

I've been creating apps without much XML, creating views programmatically. I'd like to switch to XML. So I wrote an XML file for a RelativeLayout, and I need to inflate it into an existing class (a subclass of RelativeLayout, of course) that has all the implementation logic.
How do I inflate into "this" in the constructor?
By the way, what's really the advantage of XML? When I create views in the code, I scale fonts and images and also move views around depending on the screen's size, orientation, aspect ratio, etc. With XML approach, I'd have to create a separate XML for all possible configurations...
Constructor code:
public OrderEditControl()
{
super(LmcActivity.W.getApplicationContext());
Resources res = LmcActivity.W.getResources();
setBackgroundColor(Color.TRANSPARENT);
headers = res.getStringArray(R.array.item_list_columns);
widths = new int[headers.length];
createLabels();
createButtons();
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(ALIGN_PARENT_TOP);
lp.addRule(RIGHT_OF, labels[LabelType.CUSTOMER.ordinal()].getId());
lp.addRule(LEFT_OF, buttons[ButtonType.FIND_CUSTOMER.ordinal()].getId());
customerView = new TextView(LmcActivity.W.getApplicationContext());
customerView.setTextColor(Color.BLACK);
customerView.setId(400);
customerView.setTypeface(Typeface.DEFAULT_BOLD);
customerView.setGravity(Gravity.CENTER_VERTICAL);
addView(customerView, lp);
lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(ALIGN_TOP, labels[LabelType.SHIP_TYPE.ordinal()].getId());
lp.addRule(ALIGN_BOTTOM, labels[LabelType.SHIP_TYPE.ordinal()].getId());
lp.addRule(RIGHT_OF, labels[LabelType.SHIP_TYPE.ordinal()].getId());
shipSpinner = new Spinner(LmcActivity.W);
shipSpinner.setId(401);
shipSpinner.setAdapter(shipAdapter);
shipSpinner.setOnItemSelectedListener(this);
addView(shipSpinner, lp);
deliveryView = new EditText(LmcActivity.W.getApplicationContext());
deliveryView.setGravity(Gravity.CENTER_VERTICAL);
deliveryView.setSingleLine();
deliveryView.setId(402);
addView(deliveryView);
lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RIGHT_OF, labels[LabelType.COMMENTS.ordinal()].getId());
lp.addRule(LEFT_OF, buttons[ButtonType.ITEMS.ordinal()].getId());
lp.addRule(ALIGN_TOP, labels[LabelType.COMMENTS.ordinal()].getId());
commentView = new EditText(LmcActivity.W.getApplicationContext());
commentView.setGravity(Gravity.TOP);
commentView.setId(403);
addView(commentView, lp);
lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
lp.addRule(BELOW, commentView.getId());
itemList = new ListView(LmcActivity.W.getApplicationContext());
itemList.addHeaderView(createRow(null, null), null, false);
itemList.setOnItemClickListener(this);
itemList.setAdapter(itemAdapter);
itemList.setCacheColorHint(0);
itemList.setBackgroundColor(Color.TRANSPARENT);
itemList.setId(404);
addView(itemList, lp);
lays[0] = new LayParm(false);
lays[1] = new LayParm(true);
}
/** create the view's buttons */
private void createButtons()
{
for (int i = 0; i < N_BUT; ++i)
{
Button but = i == ButtonType.ITEMS.ordinal() ?
new TextGlassButton(2.4f, LmcActivity.W.getResources().getString(R.string.items), Color.WHITE) :
new EffGlassButton(1.2f, butEffects[i]);
but.setId(BUT_ID + i);
but.setOnClickListener(this);
buttons[i] = but;
if (i == ButtonType.DATE.ordinal())
addView(but);
else
{
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
if (i < 2)
lp.addRule(ALIGN_PARENT_TOP);
else
lp.addRule(BELOW, BUT_ID + i - 2);
if (i % 2 == 0)
lp.addRule(ALIGN_PARENT_RIGHT);
else
lp.addRule(LEFT_OF, BUT_ID + i - 1);
addView(but, lp);
}
}
}
/** create text labels */
private void createLabels()
{
Paint paint = AFDraw.W.textPaint;
paint.setTextSize(Universe.TEXT_SIZE);
paint.setTypeface(LmcActivity.W.defaultTypeface);
String[] titles = LmcActivity.W.getResources().getStringArray(R.array.order_labels);
for (int i = 0; i < titles.length; ++i)
{
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(ALIGN_PARENT_LEFT);
if (i == 0)
lp.addRule(ALIGN_PARENT_TOP);
else
lp.addRule(BELOW, LABEL_ID + i - 1);
TextView tv = new TextView(LmcActivity.W.getApplicationContext());
tv.setText(titles[i]);
tv.setTextColor(Color.BLACK);
tv.setId(LABEL_ID + i);
tv.setTypeface(LmcActivity.W.defaultTypeface);
tv.setGravity(Gravity.CENTER_VERTICAL);
labels[i] = tv;
addView(tv, lp);
labelWidth = Math.max(labelWidth, paint.measureText(titles[i]));
}
labelWidth += Universe.TEXT_SIZE * 0.5f;
dateWidth = paint.measureText("00/00/00") + Universe.TEXT_SIZE * 1.5f;
}
#scriptocalypse is generally right, but subclassing some layouts and inflating custom layout to this class helps to separate different abstractions. There are so many bad tutorials, in which everything is done in the Activity. I see that the world's new comming programmers will code only crap looking applications.
With custom layout you can do in Activity only such a thing:
medicineView.putMedicine(medicineList);
instead of all crappy adapter creations and looking for views...
Firstly you should create some view for your custom View:
<RelativeLayout ...>
<!-- You put all your views here -->
</RelativeLayout>
Secondly if you are sattisfied with your view, you should change the root to merge tag:
<merge ...>
<!-- You put all your views here -->
</merge>
This is very important. We begin design with RelativeLayout tags in order to IDE know how to draw layouts, and how to do completions. But if we leave it as it is, we will end up in two nested RelativeLayouts it will be something like that in the end:
<RelativeLayout ...> <!-- That is your class -->
<RelativeLayout ...> <!-- This is inflated from layout -->
<!-- You put all your views here -->
</RelativeLayout>
</RelativeLayout>
If you change your layout to "merge" then it will look like this:
<RelativeLayout ...> <!-- That is your class -->
<merge...> <!-- This is inflated from layout -->
<!-- You put all your views here -->
</merge>
</RelativeLayout>
and will be merged to its root:
<RelativeLayout ...> <!-- That is your class, merged with layout -->
<!-- You put all your views here -->
</RelativeLayout>
At the end you must subclass demanded View or ViewGroup:
public class CustomView extends RelativeLayout {
public CustomView(Context context) {
super(context);
initialize();
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
private void initialize() {
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(R.id.your_layout, this, true);
// find your views, set handlers etc.
}
}
Usage
Just like #scriptocalypse already said. In another layout you use this like that:
<SomeLayout>
<com.foo.CustomView>
</SomeLayout>
First, to answer your main question:
you would not want to inflate an XML RelativeLayout into your RelativeLayout class. You'd extend RelativeLayout and then declare an instance of your RelativeLayout in an XML file, like so:
// com.foo.MyRelativeLayout.java
public class MyRelativeLayout extends RelativeLayout{
/**
* Implement MyRelativeLayout
*/
}
and...
// layout_example.xml
<?xml version="1.0" encoding="utf-8"?>
<com.foo.MyRelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Put More Views in here... -->
<TextView
android:id="#+id/customer_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/customer_name_placeholder" />
<!-- and on... -->
</com.foo.MyRelativeLayout>
But more to the point, if you're using the XML to lay out your file, you don't need any of those instantiations or .addRule() method invocations inside your MyRelativeLayout file because you've done it declaratively in XML instead.
To answer your second question of "Why do you want to use XML anyway?"
There are many reasons. Maybe these apply to you, and maybe they don't, but they're ones that I can think of fairly easily that have been relevant in my work.
You don't actually have to create a new layout file for every separate screen size or use case. For the most part, a single layout file will suffice for most screens. You might find that you will have size/resolution/orientation specific dimens.xml or style.xml files, but unless you want a dramatically different arrangement for your different possibilities then the layouts themselves don't repeat themselves too often.
You can use a visual editor. This is important if you're working in teams, and your teammates don't like to or want to use only Java to lay out their screens. While I and others gladly create View and Layout subclasses to fit our needs, I know of literally nobody who prefers to use Java as their primary layout language. Finding people who will work with you (or a job where everyone else uses the XML tools) could be challenging.
If you're creating tools for other people to use (like the above-mentioned folks who prefer XML) you can actually give them custom attributes to work with, that make positioning and layout more powerful. These attributes could be hard-coded in the XML, or they could be references to any of the other Android resources (drawable/string/color/integer/boolean/etc...). As a contrived example, but one based on your code, you could give your users the ability to specify a number of buttons to create rather than rely on the N_BUT variable. You could give it a default value, but offer users a way to change it in XML.
Here is an example:
// somelayout.xml
<?xml version="1.0" encoding="utf-8"?>
<com.foo.MyRelativeLayout
xmlns:param="http://schemas.android.com/apk/res-auto"
style="#style/MyRelativeLayoutStyle"
param:numberOfButtons="3">
</com.foo.MyRelativeLayout>
and in a different file...
//attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyRelativeLayout">
<attr name="numberOfButtons" format="reference|integer" />
</declare-styleable>
</resources>
and in your MyRelativeLayout, you access those attributes from the AttributeSet in its constructor (the one called by Android when it uses XML to create a layout).
Using the style="#style/foo" syntax can allow you to create "classes" of styles that can apply to all kinds of views without actually making a View subclass. Let's say you know that you always want to have a set of parameters that hold true for all your Button elements but don't want to subclass Button.
For example:
// styles.xml
<style name="BaseButton">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:background">#drawable/bg_common_button</item>
<item name="android:textColor">#color/white</item>
<item name="android:textSize">#dimens/base_button_text_size</item>
<!-- ^^ that dimen value could vary from screen size to screen size, but the style likely won't -->
</style>
// button_layout.xml
<Button
android:id="#+id/styled_button"
style="#style/BaseButton" /> <!-- and you're done -->
// some_other_layout.xml
<LinearLayout
style="#style/BaseLinearLayout">
<Button style="#style/BaseButton" android:text="Button1" />
<Button style="#style/BaseButton" android:text="Button2" />
<Button style="#style/BaseButton" android:text="Button3" />
</LinearLayout>
If you would like to instantiate that button using code, then you can use the LayoutInflater to inflate that specific button's layout and use that wherever you want. In fact, you can create all manner of components in XML and then inflate them at runtime.
LayoutInflater inflater = LayoutInflater.from(YourActivity.this);
Button theInflatedButton = inflater.inflate(R.layout.button_layout.xml, null);
Of course, the canonical example is ListViews and the items that you wish to populate them. You'd create a listview item layout xml and then inflate that whenever your Adapter is in need of a new convertView instance.

Textview style after adding dynamically

My question is how to set a textView style after adding it dynamically.
Here is the code:
LinearLayout layout = (LinearLayout)findViewById(R.id.linarLay);
TextView textView = new TextView(this);
textView.setText("TEST1");
layout.addView(textView);
I can see the text view that has been added but.. I need to style it now..
So far I tried this:
textView.setTextAppearance(getApplicationContext(),R.style.textStyle);
I tried this code after layout.addView(textView); and before it is just same doesn't change a thing..
Any idea/solution would be appreciated... Thanks
Style doesn't change because though you use the same TextView object to set style after adding it to Layout,it is not a part of layout. You have to get the View added,from layout using its id and when you change its style,it would directly be affected to your view on Layout.
Try this: (I have not tested but *should work)
LinearLayout layout = (LinearLayout)findViewById(R.id.linarLay);
TextView textView = new TextView(this);
textView.setText("TEST1");
textView.setId(999); // give some id
layout.addView(textView);
TextView tv=(TextView)findViewById(999);
tv.setTextAppearance(getApplicationContext(),R.style.textStyle);
I had a similar problem. I wanted to do the same with a button. You can set every property programmatically.
You can create a class with a set of methods like the one below:
private void setButtonStyle(Button b, String text)
{
LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 1.0f);
b.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.blue_button));
b.setGravity(Gravity.CENTER);
b.setText(text);
b.setLayoutParams(param);
b.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
b.setTypeface(null, Typeface.BOLD);
b.setShadowLayer(2, 1, 1, R.color.button_shadow_colour);
b.setTextColor(context.getResources().getColor(R.color.button_text_colour));
}
As you can see it is possible to set everything you need. As an example the param variable has 3 arguments in its contructor which are layout_width, layout_height and weight. So you can do the same with TextView.
deprecated since API 23:
textView.setTextAppearance(getContext(), R.style.Headline);
so choose:
textView.setTextAppearance(R.style.Headline);

Why is programatic layout invisible?

my TextView that I add to my LinearLayout is not visible...why ?
layoutVenues = (LinearLayout) findViewById(R.id.layoutv);
layoutVenues.addView(genTextView(v.getName()));
layoutVenues.addView(genLineView());
and the genTextView Method:
public TextView genTextView(String text) {
TextView tv = new TextView(this);
tv.setText(text);
tv.setTextColor(Color.BLACK);
return tv;
}
You need to set layout parameters otherwise you will not have a proper layout
public TextView genTextView(String text) {
TextView tv = new TextView(this);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutPararms.WRAP_CONTENT);
tv.setLayoutParams(lp);
tv.setText(text);
tv.setTextColor(Color.BLACK);
return tv;
}
Try to add visiblity to your view. .setVisibility(View.VISIBLE);
or place it in your xml and instantiating in the code will also be good idea.
I build most of my view hierarchies for Android using XML layout files, so I'm not an expert on programmatically assembling view hierarchies. However, one thing that jumps out at me is that you don't appear to set any layout parameters on the TextView that is returned by genTextView(). Also, take a look at the layout parameters of the LinearLayout in your XML file and make sure that it is actually getting assigned screen real estate.
The default background is black I believe? So you have black text on a black background. Its probably not that easy though :P Might want to post the xml where the linearlayout is defined.

How to align a dynamically create UserInterface using RelativeLayout in Android

I want to create a relative Layout dynamically through code with 2 Textviews one below the other.How to implement android:layout_below property through code in Android.
can anyone help me in sorting out this issue.
Thanks in Advance,
final TextView upperTxt = (...)
upperTxt.setId(12345);
final TextView lowerTxt = (...);
final RelativeLayout.LayoutParams params = RelativeLayout.LayoutParams(this, null);
params.addRule(RelativeLayout.BELOW, 12345);
lowerTxt.setLayoutParams(params);
Here is my solution for my special Problem.
In case the username wouldn't be found in the db i had to create a RelativeLayout that looks like the xml-generated one.
// text view appears on top of the edit text
enterNameRequest = new TextView(mainActivity.getApplicationContext());
// fill the view with a string from strings.xml
enterNameRequest.setText(mainActivity.getResources().getString(R.string.enterNameRequest));
// edit text appears below text view and above button
enterName = new EditText(mainActivity.getApplicationContext());
enterName.setId(667);
// button appears at the bottom of the relative layout
saveUserName = new Button(mainActivity.getApplicationContext());
saveUserName.setText(mainActivity.getResources().getString(R.string.useUserName));
saveUserName.setId(666);
// generate the relative layout
RelativeLayout layout = new RelativeLayout(mainActivity.getApplicationContext());
layout.setId(668);
// set a background graphic by its id
layout.setBackgroundDrawable(mainActivity.getApplicationContext().getResources().getDrawable(R.drawable.background_head_neutral));
// runtime told me that i MUST use width and height parameters!
LayoutParams params2 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params2.addRule(RelativeLayout.ABOVE, 666);
enterName.setLayoutParams(params2);
LayoutParams params3 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params3.addRule(RelativeLayout.ABOVE, 667);
enterNameRequest.setLayoutParams(params3);
LayoutParams params4 = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params4.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 668);
saveUserName.setLayoutParams(params4);
// add views
layout.addView(enterNameRequest);
layout.addView(enterName);
layout.addView(saveUserName);
/* todo: set button action */
mainActivity.setContentView(layout);
What i found out additionally:
It is not so good to manipulate the layout manually from within java!
You should better use a new Activity and set a new layout in it.
This way, the application-code is readable a lot better!
I even tried to set several layouts (not manually, but wit setContentView) in one activity, and it turned out that i didn't know where what was accessing what else... Also, i had a great problem in adding onClickListeners... so you better use -- android:onClick="myButtonMethod" -- in your button tag in the xml and have a method in your according activity, which uses the layout, like this:
public void myButtonMethod(View v){
// do stuff
}
This improves performance because you are not using additional Listeners - but you use the already available Listener that is bound to your activity in every case.
u can try this
LinearLayout.LayoutParams leftMarginParams = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);``
leftMarginParams.leftMargin = 50;
Button btn1 = new Button(this);
btn1.setText("Button1");
linLayout.addView(btn1, leftMarginParams)

Creating a layout within a View-extended class

I am still pretty new to Android development, and I have not been able to find any examples of how to do this.
In my Activity, I use "setContextView(new myViewClass)" to designate a View-extended class as the one to load. Everything works fine in terms of loading the view, where I create various elements (LinearLayouts, buttons, etc.) based on a number of conditions. Unfortunately, I cannot get any of these elements to actually appear on the screen.
I guess my question goes to a greater understanding of Views. All of the examples I've seen concern setting an xml file as the base view and then altering it within the code. Is there some alternative to this?
Thanks.
Here is an example code I've been trying to make work. There are other things going on, but this is the relevant info. For program context, this class is substantiated with the setContextView(new createView(this)):
public createView(Context c){
super(c);
// Create a simple layout
LinearLayout layout = new LinearLayout(top.getContext());
layout.setOrientation(LinearLayout.VERTICAL);
// Create test text
TextView mTestText = new TextView(c);
mTestText.setText("This is a test");
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 10, 10, 10);
layout.addView(mTestText, lp);
}
I think the problem is that you are not adding the layout to your CreateView. However, the View class does not have an add method (see http://developer.android.com/reference/android/view/View.html).
Since LinearLayout is the base view for your extended view, you could extend LinearLayout instead and add the TextView to your extended class. If you do this, your CreateView class would probably look something like this:
/**
* Since the LinearLayout is the base layout, we'll extend it.
*/
public class CreateView extends LinearLayout {
public CreateView(Context context) {
super(context);
setOrientation(LinearLayout.VERTICAL);
TextView mTestText = new TextView(context);
mTestText.setText("This is a test");
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 10, 10, 10);
addView(mTestText, lp);
}
}

Categories

Resources