How to programmatically add content to custom XML layout? - android

I'm making a custom XML layout to display a cocktail recipe. Here is my XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/drinkname" android:layout_height="wrap_content"
android:textSize="30sp" android:text="#string/drink_name"
android:layout_width="wrap_content" android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<TextView android:layout_width="fill_parent"
android:layout_height="2dp" android:background="#FFFFFFFF"
android:layout_below="#id/drinkname" />
<TextView android:layout_height="wrap_content" android:id="#+id/ingredient_label"
android:text="Ingredients: " android:layout_width="wrap_content"
android:layout_below="#+id/drinkname" android:layout_marginLeft="10dp"
android:layout_marginTop="16dp" />
<TableLayout android:layout_height="wrap_content"
android:id="#+id/ingredient_table" android:layout_width="wrap_content"
android:layout_alignTop="#+id/ingredient_label"
android:layout_alignLeft="#+id/drinkname"
android:layout_alignParentRight="true">
<TableRow android:id="#+id/tableRow1" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:text="• 2 oz. Gin (Boodles)"android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow android:id="#+id/tableRow2" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:text="• 2 oz. Vodka (Stolichnaya)"
android:id="#+id/textView2" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</TableRow>
<TableRow android:id="#+id/tableRow3" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:text="• 1/2 oz. Vermouth, dry" android:id="#+id/textView3"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</TableRow>
<TableRow android:id="#+id/tableRow4" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:text="• 3 pieces Olive" android:id="#+id/textView4"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<TextView android:id="#+id/instruction_label"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_below="#id/ingredient_table" android:layout_alignLeft="#id/ingredient_label"
android:text="Instructions: " android:layout_marginTop="25dp" />
<TextView android:id="#+id/instructions"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_alignTop="#id/instruction_label"
android:layout_alignLeft="#id/drinkname"
android:layout_alignParentRight="true" android:text="#string/drink_instructions" />
<TextView android:id="#+id/glass_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_below="#id/instructions"
android:layout_alignLeft="#id/ingredient_label" android:text="Glass:"
android:layout_marginTop="25dp" />
<TextView android:id="#+id/glass_type"
android:layout_toRightOf="#id/glass_label" android:text="#string/drink_glass"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_alignTop="#id/glass_label" android:layout_alignLeft="#+id/drinkname" />
As you can see all the content displayed is written into the layout itself or is taken from a string resource. My question is: what would I have to do to keep the layout I created below, but be able to fill in the content programmatically?

You would have to do something like this...
(TextView) this.findViewById(R.id.drinkname).setText("Water");
Use findView to get a reference to a particular view on the activity. Pass it the Resource identifier you gave in the XML (the id property). Cast it to the correct View type, and then set it's properties.
The resource id's are created automatically from the id attribute in XML, and added to the R class inside R.id..
As an example from the application I'm currently writing, I usually define the views I'm going to be modifying as class level fields near the beginning of the class like so:
TextView tvGameDate;
TextView tvGameTime;
TextView tvHomeTeam;
TextView tvAwayTeam;
TextView tvHomePitcher;
Then near the start of onCreate I will populate them all with the references to the actial views like this:
tvGameDate = (TextView) this.findViewById(R.id.tvGameDate);
tvGameTime = (TextView) this.findViewById(R.id.tvGameTime);
tvHomeTeam = (TextView) this.findViewById(R.id.tvHomeTeam);
tvAwayTeam = (TextView) this.findViewById(R.id.tvAwayTeam);
tvHomePitcher = (TextView) this.findViewById(R.id.tvHomePitcher);
Then I can just refer to the fields I defined whenever I need to access them like this:
tvHomeTeam.setText(attributes.getNamedItem("home_long").getNodeValue());
tvHomePitcher.setText(" (" + attributes.getNamedItem("home_pitcher").getNodeValue() + ")");
In your XML it looks like you may actually need to dynamically create additional text views on the fly based on the recipe. You can do this like so (where llIngredients maps to some LinearLayout in your XML):
TextView tv = new TextView(context);
tv.setTextColor(Color.BLACK);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tv.setText("Some text for the new view");
llIngredients.addView(tv);

Not sure I follow you. I'm guessing this resource represents an activity. You can get a reference to your text view, lets say glass_type by saying -
TextView glassTypeTxtView = findViewById(R.id.glass_type) and set its content dynamically by saying glassTypeTxtView.setText("new text").
Please correct me if I misunderstood your question completely.

Related

How to get value from a TextView which is in a ListView without any custom adapters?

I have a ListView with a TextView (which has an integer as string) and a Seekbar.
I need to extract the integer value and set it to the Seekbar.
Unfortunately, when I do this, I get a NullPointer exception because the content that populates the ListView item is not recognized by the onCreateView of the PlaceholderFragment.
String progressValue = percentileTextView.getText().toString();
bar.setProgress(Integer.parseInt(progressValue));
I have an activity layout for this activity, then a fragment layout which contains the listview and then I have a content.xml where the actual TextView is present. My question is how to reference this TextView? Am I doing this right, i.e. Activity layout contains a ConstraintLayout with Toolbars etc, then the Fragment Layout contains the ListView and I am using a separate content.xml and applying that to the ListView via a SimpleAdapter.
newAdapter = new SimpleAdapter(getContext(), newList,
R.layout.content, new String[] {
"name",
"percent"
},
new int[] {
R.id.name1,
R.id.percentile1
});
I hope you understand my problem.
When I do the following, it works (i.e. Android Studio understand that is the TextView) - but throws a null pointer exception upon build.
TextView percentileTextView = (TextView) rootView.findViewById(R.id.percentile1);
UPDATE 1 for pskink:
Newlist contents:
[{TA=Item1, IA=46}, {TA=Item2, IA=98}, {TA=Item3, IA=70}, {TA=Item4, IA=54}, {TA=Item5, IA=99}, {TA=Item6, IA=98}]
Row item layout (content.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="#dimen/activity_horizontal_margin">
<TextView
android:id="#+id/name1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:textStyle="bold"
android:textColor="#color/colorAccent" />
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="5dp">
<TextView
android:id="#+id/greater_than"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="#string/greater_than" />
<TextView
android:id="#+id/percentile1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:layout_toRightOf="#id/greater_than"
android:layout_toEndOf="#id/greater_than"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:layout_toRightOf="#id/percentile1"
android:layout_toEndOf="#id/percentile1"
android:text="#string/percentile_text"/>
</RelativeLayout>
<SeekBar
android:id="#+id/seekBar2"
android:paddingTop="12dip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end|bottom"
android:paddingTop="12dip"
android:orientation="horizontal">
<ImageView
android:contentDescription="info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/someimg" />
</LinearLayout>
</LinearLayout>

Building table layout dynamically at run time from XML

New to android, I would like to have a view like below with actual values.
My code to dummy values is as below:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp">
<TableRow
android:background="#607D8B"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Title" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Due On" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="" />
</TableRow>
<TableRow
android:background="#ECEFF1"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Access to Knowledge" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="12 Feb 2016" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Renew" />
</TableRow>
<TableRow
android:background="#ECEFF1"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Achivement" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="16 Feb 2016" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Renew" />
</TableRow>
<TableRow
android:background="#ECEFF1"
android:padding="5dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="God of small things" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="22 Feb 2016" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Renew" />
</TableRow>
<Button
android:text="Renew all" />
</TableLayout>
I am getting the values from XML from webservices and parsing it to show in my table view.
I am using DocumentBuilderFactory to parse my XML. Here my XML file is in String str.
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource src = new InputSource();
src.setCharacterStream(new StringReader(str));
Document doc = builder.parse(src);
String title = `doc.getElementsByTagName("title").item(0).getTextContent();`
Normally I use
TitleTxt.setText("Title: " + title);
PublisherTxt.setText("Publisher: " + publisher)
to show the results in my view.
I have multiple questions:
Q1 what modifications are needed in layout file to show - actual values and not the dummy values?
Q2 how to get the array values in XML parsing to show in my layout file?
Q3 how to show the XML parsed results in my table view - dynamically at runtime?
These are related queries, so had to put in the same question. Some of it may sound simple, but being new to Android, I am not able to figure out. Also tried to find a sample code to do it but could not find. Not sure if I am using the right keywords to search for what I am looking for.
Any links to sample code or which exact keywords to look for to search my issue solution or suggestions will also be appreciated.
Thanks in advance.
In order to add new Views to another at runtime, you can use the View.add method. So, in order to make the above table "dynamic", you can alter your layout file to just contain the TableLayout. And later, at runtime you programmatically add TableRows to the TableLayout.
Basically, there are two options how to add a TableRow then.
First, you can construct your TableRow, e.g.:
TextView tvTitle = new TextView(...);
TextView tvDueOn = new TextView(...);
Button btnRenew = new TextView(...);
TableRow tr = new TableRow(...);
tr.add(tvTitle);
tr.add(tvDueOn);
tr.add(btnRenew);
TableLayout lytTable = (TableLayout)findViewById(...);
lytTable.add(tr);
This is just a minimal version, but with adding the views weight, layout_width and layout_height, you can achieve this.
Second, you can design your TableRow in a layout XML file, which you can then load and add to the TableLayout at runtime using LayoutInflater.
lytTableRow.xml
<TableRow
android:id="+#id/lytTableRow"
android:background="#607D8B"
android:padding="5dp">
<TextView
android:id="+#id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="+#id/tvDueOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="+#id/btnRenew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="" />
</TableRow>
code in Activity
TableLayout lytTable = (TableLayout)findViewById(R.id.lytTable);
View tableRow = getLayoutInflater().inflate(R.layout.lytTableRow, null);
TextView tvTitle = (TextView)tableRow.findViewById(R.id.tvTitle);
TextView tvDueOn = (TextView)tableRow.findViewById(R.id.tvDueOn);
Button btnRenew = (Button)tableRow.findViewById(R.id.btnRenew);
tvTitle.setText(...);
Both code-parts can be put into a loop for instance, in order to add your multiple rows - but pay attention to set tags/ids to your views using view.setTag in order to be able to distinguish them later in the Button click listener for instance.
Concerning the data, depending on what kind of XML parser you use, you can loop through every item in the data and add them to your TableLayout using one of the options shown above. According to your question, you use a DOM parser. You can loop through the items using a NodeList retrieved from doc.getElementsByTagName("parentnodename") where parentnodename is the element name which contains "title", "dueon" etc.

Set clickable url link in textview

My String is somthing conbination of url string and url within href like:
" Go http://www.google.co.in for more detail click here"
No i need to show clickable both:
1- http:www.google.co.in
2- here
and clicking on both the link it should show the respective url.
Use android:autoLink="web" in your XML file.
Or
Just use an HTML format link in your resource (Strings.xml):
<string name="my_link"><a ref="http://somesite.com/">Click me!</a></string>
You can then use setMovementMethod(LinkMovementMethod.getInstance()) on your TextView to make the link clickable.
You can try:
// text2 has links specified by putting <a> tags in the string
// resource. By default these links will appear but not
// respond to user input. To make them active, you need to
// call setMovementMethod() on the TextView object.
TextView t2 = (TextView) findViewById(R.id.text2);
t2.setMovementMethod(LinkMovementMethod.getInstance());
Another Way:
https://stackoverflow.com/a/17544212/1318946
Edited:
Its not perfectly right solution but you can solve your problem using this one.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Go"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#+id/textView1"
android:text="Google.com"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#0000ff" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:layout_marginTop="5dp"
android:text="For more Details"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView3"
android:layout_alignBottom="#+id/textView3"
android:layout_marginLeft="5dp"
android:layout_toRightOf="#+id/textView3"
android:text="Click here"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#0000ff" />
Output is looks like:
Now you have to define onClickListener for textView2 and textView4 and you can do want you want. :)
Happy Coding.

ImageView dissapearing after setting an ID

I'm programatically adding views into my layout inside a for loop.
The xml file of the layout I'm adding is like this one:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout_consulta_item_list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView_consulta_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/LinearLayout_dados_consulta"
android:layout_alignParentRight="true"
android:layout_alignTop="#+id/LinearLayout_dados_consulta"
android:layout_centerHorizontal="true"
android:layout_centerInParent="false"
android:adjustViewBounds="true"
android:maxWidth="70dp"
android:padding="10dp"
android:scaleType="centerInside"
android:src="#drawable/estrela_off" />
<LinearLayout
android:id="#+id/LinearLayout_dados_consulta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2dp"
android:layout_toLeftOf="#+id/imageView_consulta_action"
android:background="#660000"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:text="#string/origem"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#ffaaaa"
android:textSize="10sp" />
<TextView
android:id="#+id/textView_origem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YYY"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#eeeeee" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:text="#string/data_ida"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#ffaaaa"
android:textSize="10sp" />
<TextView
android:id="#+id/textView_data_ida"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2014-05-05"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#eeeeee"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
In my main_activity, I call the constructor:
for (int i=0;i<resultList.length-1;i++){
RelativeLayout viewToLoad = (RelativeLayout)LayoutInflater.from(this).inflate(R.layout.consulta_item, null);
ll.addView(viewToLoad);
ImageView ImgConsulta_action = (ImageView)findViewById(R.id.imageView_consulta_action);
LinearLayout dados_consulta = (LinearLayout)findViewById(R.id.LinearLayout_dados_consulta);
dados_consulta.setOnLongClickListener(...);
ImgConsulta_action.setOnLongClickListener(...);
Well, I keep setting SetText for all the views in the layout and so on.
But, in order to make the setOnClickListener to work for each view, I must set a id to the views inside the for loop:
dados_consulta.setId(4000+i);
ImgConsulta_action.setId(5000+i); //(*lastline)
The weird thing is happening is that:
If I comment this last line, the layout is inserted correctly with the imageview showing a star as it is suposed to do and the listener at "dados_consulta" works fine.
But if I remove the comment at this last line, the star dissapear from the screen.
Can anybody help me to understand what is going on?
I had an layout params referenced to the ID of the layout elements at the original view.
Since I have to change the ID dynamically while I'm adding this layout several times into my activity, I also need to reset the layoutparams to the new Ids.
So, I added this lines:
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)ImgConsulta_action.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_TOP, dados_consulta.getId());
params.addRule(RelativeLayout.ALIGN_BOTTOM, dados_consulta.getId());
ImgConsulta_action.setLayoutParams(params);
RelativeLayout.LayoutParams paramsDadosConsulta = (RelativeLayout.LayoutParams)dados_consulta.getLayoutParams();
paramsDadosConsulta.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
paramsDadosConsulta.addRule(RelativeLayout.LEFT_OF, ImgConsulta_action.getId());
dados_consulta.setLayoutParams(paramsDadosConsulta);
Now it's working perfectly.
Notice that the problem is not about the layout disappearing it was about a layout get in front of the other one. (making this other one invisible)

Android: Layout with row span

I am trying to figure out how to create a layout that looks like this.
--------------------------------
Sep Text here
--------------------------------
text 1 here | IMG
text 2 Here |
--------------------------------
I have tried to do this with a table layout inside of a table layout but than I am having trouble accessing the "text 1" and text 2" to set their values. Any thoughts on how I should accomplish this? Or maybe you can tell me how to access elements that are down two levels of layouts.
This can be easily accomplished with a RelativeLayout. It would be implemented in the lines of the following:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/img"
android:src="#drawable/my_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:layout_alignParentRight="true" />
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/header"
android:layout_alignParentLeft="true" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/text1"
android:layout_alignParentLeft="true" />
</RelativeLayout>
Accessing text1 and text2 by code could be done by:
TextView text1 = (TextView) findViewById(R.id.text1);
TextView text2 = (TextView) findViewById(R.id.text2);
// set text
text1.setText("foo");
text2.setText("bar");
Hope it helps!

Categories

Resources