How do I get a custom component that extends RelativeLayout programmatically? - android

Being new to Android the following issue drives me crazy, and not being able to Google an answer indicates that the solution is really simple...
I try to add a custom component (ArticleView extends RelativeLayout) to a ViewGroup (LinearLayout) from code but I cannot get access to the ArticleView object, trying to cast to it just throws an
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.eo.read/com.example.eo.read.ArticleInfoActivity}: java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to com.example.eo.read.view.ArticleView
Caused by: java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to com.example.eo.read.view.ArticleView
at com.example.eo.read.ArticleInfoActivity.onCreate(ArticleInfoActivity.java:44)
In my Activity class I do:
package com.example.eo.read;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.example.eo.read.content.Article;
import com.example.eo.read.content.ArticleDB;
import com.example.eo.read.view.ArticleView;
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article_info);
_article = ArticleDB.getInstance().getArticle("test");
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//get the linear layout into which the ArticleView is going
LinearLayout container = (LinearLayout) findViewById(R.id.recommendation_container);
//get the custom component
RelativeLayout ra = (RelativeLayout)inflater.inflate(R.layout.article_view, container, false);
//this causes the classcast exception, although this RelativeLayout really should be an ArticleView
((ArticleView)ra).setArticle(_article);
//adding the ArticleView to the container works fine, and the customizations
//I have made in ArticleView are visible, so indeed it seems ra is an ArticleView ??
container.addView(ra);
}
The (simplified) article_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="260dp" android:layout_height="wrap_content" android:background="#drawable/stroked_grey_plate">
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:textSize="16sp"
android:text="Sample text"
android:textColor="#111111"
android:scrollHorizontally="true"
android:ellipsize="end"
android:maxLines="1"
/>
</RelativeLayout>
The layout for the activity contains the id/recommedation_container into which the ArticleView is being inserted. Below is also the same view inserted declaratively, just for clarity:
<LinearLayout
android:id="#+id/recommendation_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp">
<com.example.eo.read.view.ArticleView
android:layout_width="wrap_content" android:layout_height="wrap_content"
custom:titleText="my title text"
/>
</LinearLayout>
The ArticleView class is essentially:
package com.example.eo.read.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.eo.read.R;
import com.example.eo.read.content.Article;
public class ArticleView extends RelativeLayout {
private TextView _titleView;
private Article _article;
public ArticleView(Context context) {
this(context,null);
}
public ArticleView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ArticleView, 0, 0);
//in the case where the ArticleView is declared in XML the title is retreived from a custom attribute, this works fine.
String titleText = a.getString(R.styleable.ArticleView_titleText);
a.recycle();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.article_view, this, true);
ViewGroup rl = (ViewGroup)getChildAt(0); //get the RelativeLayout
_titleView = (TextView) rl.getChildAt(0);
_titleView.setText(titleText);
}
//in the case where the ArticleView is initiated from code the title should be set by calling this method,
//which I never can reach since I cannot get to this ArticleView object from my activity :-(
//I realize this class is maybe not fully functional yet but first step is to actually be able to initiate it...
public void setArticle(Article a) {
_article = a;
_titleView.setText(_article.getTitle());
}
}
So, my question is pretty much.. why can't I do:
ArticleView ra = (ArticleView)inflater.inflate(R.layout.article_view, container, false);
and what should I instead do to get to my ArticleView?

Replace ArticleView in your XML file with [packagename].ArticleView
For example, if your ArticleView class is contained in com.john.article, then your ArticleView should be replaced by com.john.article.ArticleView.

If I understand you correctly, you want to add the custom view programmatically and not have it defined in the XML?
If that is the case, what happens if you simply do:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_article_info);
_article = ArticleDB.getInstance().getArticle("test");
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//get the linear layout into which the ArticleView is going
LinearLayout container = (LinearLayout) findViewById(R.id.recommendation_container);
//get the custom component
ArticleView av = new ArticleView(this);
av.setArticle(_article);
container.addView(av);
}
In case you haven't stumbled upon it yet, it seems this blog has some nice tips regarding custom views: http://trickyandroid.com/protip-inflating-layout-for-your-custom-view/
If you would like to have your Custom view inflated together with your layout, then you can do:
<LinearLayout
android:id="#+id/recommendation_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="10dp">
<com.example.eo.read.view.ArticleView
android:id="#+id/article"
android:layout_width="wrap_content" android:layout_height="wrap_content"
custom:titleText="my title text"
/>
</LinearLayout>
Just taking the XML from your question as an example, not sure how well it fits your situation.
But now, inflating the above XML to a view called, say, root and then doing root.findViewById(R.id.article) should return a view which can be cast to ArticleView.
Thinking about it, if you have an XML file like this:
<com.example.eo.read.view.ArticleView
android:layout_width="wrap_content" android:layout_height="wrap_content"
custom:titleText="my title text"
/>
You actually should be able to inflate it, as you are trying, and cast to ArticleView, since com.example.eo.read.view.ArticleView is now the root of the layout.

Related

Android inflating views from other layouts

I'm relatively new to android development and I'm trying to find a way to inflate a view repeatedly each time when a button is pressed, in a different location, so every inflated view has its own position:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class teamCreateScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.team_locate_layout);
}
public void createTeam(View view) {
final RelativeLayout rlTeam = (RelativeLayout) findViewById(R.id.rlTeam);
View teamBox = View.inflate(this, R.layout.team_box, rlTeam);
final TextView teamBoxView = (TextView) findViewById(R.id.team_task_box);
teamBoxView.setX(0);
teamBoxView.setY(230);
}
}
The XML code of the layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rlTeam">
<Button
android:layout_width="60dp"
android:layout_height="60dp"
android:id="#+id/teamAddBtn"
android:text="+"
android:textSize="30sp"
android:onClick="createTeam"/>
</RelativeLayout>
XML code of the view that's being inflated:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="192dp"
android:layout_height="120dp"
android:id="#+id/team_task_box"
android:text="New Team" />
</RelativeLayout>
I want to use the same view to inflate multiple boxes with different coordinates in the layout. Every time I press the button to inflate the view again it inflates the box in the same coordinates so they overlap. I need to make the second box to appear to the first one's right, the third below 1st and so on, much like a grid of boxes.
Try this code and tell me whether it works. Remove the inflating of layout
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class teamCreateScreen extends Activity {
int i=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.team_locate_layout);
}
public void createTeam(View view) {
final RelativeLayout rlTeam = (RelativeLayout) findViewById(R.id.rlTeam);
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
TextView tv=new TextView(getApplicationContext());
if(tv.getId()>0) {
relativeParams.addRule(RelativeLayout.BELOW, tv.getId());
}
tv.setId(i);
r1Team.addView(tv, relativeParams);
i++;
}
}
Declare int i=0; as a global variable and increment it in the createTeam() method.

Trying to inflate layout in Activity not working

I'm trying to add a custom view that I made to an adapter of mine. I'm trying to do this to add a view to merge adapter by commonsware.
https://github.com/commonsguy/cwac-merge
This is my code of me trying to inflate the layout:
LayoutInflater inflater = getLayoutInflater();
LinearLayout row = (LinearLayout) inflater.inflate(R.layout.row,
null);
TextView headerOne = (TextView) row
.findViewById(R.id.titleTextView);
TextView headerTwo = (TextView) row
.findViewById(R.id.titleTextView);
headerOne.setText("One");
headerTwo.setText("Two");
mergeAdapter.addView(headerOne);
mergeAdapter.addAdapter(myArrayAdapter);
mergeAdapter.addView(headerTwo);
mergeAdapter.addAdapter(myOtherArrayAdapter);
This is my xml.
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_weight="1"
android:orientation="vertical" >
<TextView
android:id="#+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-condensed"
android:text="message text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#color/text_gray"
android:textStyle="bold" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="#000000" />
</LinearLayout>
Update: Forgot to talk about what my "problem" is. First, is that I've never inflated a layout before so I'm unsure of how it works/whats the proper way to inflate. Second, I get this error:
01-20 23:18:46.427: E/AndroidRuntime(24810): java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
EDIT:
My imports:
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockListActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.commonsware.cwac.merge.MergeAdapter;
import com.google.gson.JsonObject;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import com.eghdk.myapp.R;
import com.eghdk.myapp.util.AppUtil;
import com.eghdk.myapp.util.DatabaseHelper;
public class MyActivity extends SherlockListActivity {
Use two layout resources, not one. Do not inflate a layout, then attempt to take pieces of that layout and use them separately.
Or, to put it another way, the value you pass to addView() needs to be either:
the direct result from inflate(), or
something you create in Java using constructors
try this...
LayoutInflater inflater = getLayoutInflater();
LinearLayout row = (LinearLayout) inflater.inflate(R.layout.row, null);
TextView headerOne = (TextView) row.findViewById(R.id.titleTextView);
headerOne.setText("One");
ViewParent parent = row.getParent();
if(parent != null && parent instanceof ViewGroup) {
((ViewGroup)parent).removeView(row);
}
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(layoutParams);
mergeAdapter.addView(row);
mergeAdapter.addAdapter(myArrayAdapter);
row = (LinearLayout) inflater.inflate(R.layout.row, null);
TextView headerTwo = (TextView) row.findViewById(R.id.titleTextView);
headerTwo.setText("Two");
parent = row.getParent();
if(parent != null && parent instanceof ViewGroup) {
((ViewGroup)parent).removeView(row);
}
layoutParams = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
row.setLayoutParams(layoutParams);
mergeAdapter.addView(row);
mergeAdapter.addAdapter(myOtherArrayAdapter);
Change your below line
LinearLayout row = (LinearLayout) inflater.inflate(R.layout.row,
null);
to
View row = inflater.inflate(R.layout.row,
null);
I think, you didn't add the view to parent
try
yourParent.addView(row);
Where yourParent is the layout where you need to attach this row
Try to remove following line.
LinearLayout row = (LinearLayout) inflater.inflate(R.layout.row, null);
Instead this put following code.
View row = inflater.inflate(R.layout.row, null);
Please follow good practices while inflating layout in android http://www.doubleencore.com/2013/05/layout-inflation-as-intended/
http://www.piwai.info/android-adapter-good-practices/

Creating custom view from xml

I would like to add the same horizontal scrollable row of buttons like so
<HorizontalScrollView [...]>
<LinearLayout [...] android:orientation="horizontal">
<Button android:id="#+id/btn1" [..] />
<Button [..] />
[...]
</LinearLayout>
</HorizontalScrollView>
(toolbar.xml) to the bottom of every activity in my application. Rather than have to specify the click listeners for each button in every single activity, I'd like to be able to do all of that in one place and then just import the control each time. I figure I can do something like
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.example.ButtonBar android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_alignParentBottom="true"
android:layout_below="#+id/pagecontent" />
<LinearLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/pagecontent">
<!-- the rest of each activity's xml -->
</LinearLayout>
to include the button bar on the screen, and then do something like
package com.example;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.HorizontalScrollView;
public class ButtonBar extends HorizontalScrollView implements OnClickListener
{
public ButtonBar(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.toolbar, null);
Button btn1 = (Button) view.findViewById(R.id.button1);
btn1.setOnClickListener(this);
// and so on for the rest of the buttons
addView(View);
}
#Override
public void onClick(View v)
{
Intent intent = null;
if (v.getId() == R.id.btn1)
{
intent = new Intent(getContext(), FirstScreen.class);
}
else if (v.getId() == R.id.btn2)
{
intent = new Intent(getContext(), SecondScreen.class);
}
// and so on
if (intent != null) getContext().startActivity(intent);
}
}
but then what? How do I actually get it to display? Are there other methods I should be overriding? Is there a better / more appropriate way of doing this?
Take a look at a custom control ProgressView in my app BBC News, and one layout that uses it.
http://svn.jimblackler.net/jimblackler/trunk/workspace/NewsWidget/src/net/jimblackler/newswidget/ProgressView.java
http://svn.jimblackler.net/jimblackler/trunk/workspace/NewsWidget/res/layout/progress_view.xml
http://svn.jimblackler.net/jimblackler/trunk/workspace/NewsWidget/res/layout/main.xml

How to pass AttributeSet to custom View

How do I pass the current AttributeSet to a custom View class? If I use a constructor that only has Context in the arguments, I lose all themes and the ability to use "style" tags in the xml for that custom View.
What I've done is create an activity that contains my custom view already in the xml file, and then programmatically create a new one and add it to the layout. What I find is the one that is made in the xml has the proper styling, and the one I create programmatically doesn't.
The difference between the two as far as I can tell is that the system uses the CustomLayout1(Context context, AttributeSet attrs) constructor. The problem is I can't figure out how to get the AttributeSet for the application to pass to this custom view when I create it programmatically.
Here's the Activity:
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
public class ThemeOne extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById(R.id.mainlayout);
layout.addView(new CustomLayout1(getApplicationContext()));
}
}
Here's the main xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="#+id/mainlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.clearsync.test.theme1.CustomLayout1 android:id="#+id/maincustom"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The custom view class:
import com.clearsync.test.theme1.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
public class CustomLayout1 extends LinearLayout {
private Context context = null;
public CustomLayout1(Context context) {
super(context);
this.context = context;
create();
}
public CustomLayout1(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
create();
}
private void create(){
LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.inflateme, this, true);
}
}
and finally, the custom view xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Oh, Hewroh..."
style="?textview_style1" />
</LinearLayout>
Instead of building it with layout.addView(new CustomLayout1(getApplicationContext())); inflate it with the LayoutInflater in your Activity.
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.yourcustomviewxml, layout);
Your code creates LinearLayout inside of linear layout for your custom view. Correct way of doing this is changing your custom view xml from:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Oh, Hewroh..."
style="?textview_style1" />
</LinearLayout>
to
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Oh, Hewroh..."
style="?textview_style1"
/>
</merge>
What are you trying to accomplish here? Looks like you have an endless recursive loop here using your create method, as inflate() will call the constructor that takes attributes. Anyways to answer your question you get the attributes in the constructor with the attributes!
That is the constructor that is called when loading from XML, otherwise it calls one of the other constructors that you supply.
One other helpful thing, you can get a reference to the inflater much easier from the static View method. View.inflate :D

Fail on trying to findViewById for nested TextView (within ListView)

Trying to have a ListView (scrollable list) of rows made of two TextViews. I have a list of items from a database that I want to populating into the LinearLayout->ListView->TextView but can't get to the id...
Layout somewhat like this instructional link, but have backed away from RelativeLayout and using LinearLayout to get it working. Not even worried about how it looks yet; just can't get it wired together yet.
http://android-developers.blogspot.com/2009/02/android-layout-tricks-1.html
Have two XML files (very abbreviated details below)
main.xml and stuff.xml
main.xml has
...TextView
...ListView
stuff.xml has
... android:id="#+id/firstLine"
...
android:id="#+id/secondLine"
YES, I do setContentView(R.layout.main); right after onCreate.
Getting null on findViewByID(firstLine) and findViewID(secondLine).
I have an ArrayAdapter where I inflate the stuffView. My thinking and understanding of other examples is it's not inflated (this nested stuffView) until I purposely inflate it. That all works fine but when I do the findViewById it returns null and thus I can't setText().
epic Fail due to complete ignorance/newbieness on my part. Note: I've pored through what I can of Reto's book, especially a simliar example on Page 163 but fail fail fail...
Can some kind soul point me in the right direction?
Must I inflate this nested view? (Reto's example does). If so, what am I missing? I'm hoping someone can point me to a better example. My code's probably too involved at this point to post and a bit proprietary.
Thanks
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/identText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="some text here"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
thing_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/identText"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="some text here"
/>
<ListView
android:id="#+id/myListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
A pojo called Thingy (not copying Thingy.java here - very simple)
The main class: ShowLayoutNicely.java
package com.blap.test;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.TextView;
public class ShowLayoutNicely extends Activity {
ListView myListView;
TextView myTextView;
ArrayList<Thingy> thingys;
ThingyAdapter aa;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myListView = (ListView) findViewById(R.id.myListView);
myTextView = (TextView) findViewById(R.id.identText);
thingys = new ArrayList<Thingy>();
aa = new ThingyAdapter(this, android.R.layout.simple_list_item_1, thingys);
myListView.setAdapter(aa);
// real deal has a call to go find items from database, populate array and notify of change.
Thingy thing1 = new Thingy("first", "first row");
thingys.add(thing1);
// sadly - this isn't triggering getView() which I've overriden...
aa.notifyDataSetChanged();
Thingy thing2 = new Thingy("second", "second row");
thingys.add(thing2);
aa.notifyDataSetChanged();
}
}
The adapter override class ThingyAdapter.java
package com.blap.test;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ThingyAdapter extends ArrayAdapter<Thingy> {
int resource;
public ThingyAdapter (Context _context, int _resource, List<Thingy> _items){
super( _context, _resource, _items);
resource = _resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout thingView;
Thingy thingItem = getItem(position);
String identString = thingItem.getIdent();
String nameString =thingItem.getName();
if (convertView == null){
thingView= new LinearLayout(getContext());
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View nuView = vi.inflate(resource, thingView, true);
}
else{
thingView = (LinearLayout) convertView;
}
//here's the problem - these calls return nulls.
TextView row1 = (TextView)thingView.findViewById(R.id.firstLine);
TextView row2 = (TextView)thingView.findViewById(R.id.secondLine);
//and naturally these puke ingloriously....
row1.setText(thingItem.getIdent());
row2.setText(thingItem.getName());
return thingView;
}
}
So this code is in essence what I'm looking for help on; neutered the names to call it Thingy.... This sample isn't triggering the getView(). That's a secondary problem I have to sort out. More importantly, your help on the findViewById failure and if I've got the XML right would help a bunch.
Where you are inflating your layout you can use findViewById on the layout that you are inflating, as I don't know what your code is like here is an example of what I would do:
LayoutInflater li = LayoutInflater.from(mContext);
LinearLayout mLayout = (LinearLayout) li.inflate(R.layout.stuff,null);
View mView = mLayout.findViewById(R.id.firstLine);
You probably want your null to be the parent that you want your inflated layout to have. Hope this helps!
Update
I'd try replacing what you have as:
thingView= new LinearLayout(getContext());
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View nuView = vi.inflate(resource, thingView, true);
with:
LayoutInflater vi = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
thingView = vi.inflate(R.layout.thing_item, null);
As you seem to make a new linearlayout for no reason, as your inflation will already be have a linear layout from your xml file. This is pretty much what I said above, and this works for me :)

Categories

Resources