The get view method from the script below crashes everytime I ran the app (the error points to that method ) this is the error :
07-11 17:25:01.147 8512-8512/com.example.android.quakereport E/AndroidRuntime:
FATAL EXCEPTION: main
Process: com.example.android.quakereport, PID: 8512
android.content.res.Resources$NotFoundException: Resource ID #0x0
and this is the ArrayAdapter from the getview method code :
public class EarthQuakeAdapter extends ArrayAdapter<Earthquake> {
public EarthQuakeAdapter(Activity context, ArrayList<Earthquake> Earthquakes) {
// Here, we initialize the ArrayAdapter's internal storage for the context and the list.
// the second argument is used when the ArrayAdapter is populating a single TextView.
// Because this is a custom adapter for two TextViews and an ImageView, the adapter is not
// going to use this second argument, so it can be any value. Here, we used 0.
super(context, 0, Earthquakes);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
return super.getView(position, convertView, parent);
}
Earthquake currentEarthquake = getItem(position);
TextView magnitude = (TextView) listItemView.findViewById(R.id.magnitude);
// Get the version name from the current AndroidFlavor object and
// set this text on the name TextView
magnitude.setText(Earthquake.getmMagnitude());
// Find the TextView in the list_item.xml layout with the ID version_number
TextView place = (TextView) listItemView.findViewById(R.id.Place); // Get the version number from the current AndroidFlavor object and
// set this text on the number TextView
place.setText(Earthquake.getMplace());
// Find the ImageView in the list_item.xml layout with the ID list_item_icon
TextView date = (TextView) listItemView.findViewById(R.id.Date);
date.setText(Earthquake.getmDate());
// Get the image resource ID from the current AndroidFlavor object and
// set the image to iconView
// Return the whole list item layout (containing 2 TextViews and an ImageView)
// so that it can be shown in the ListView
return listItemView;
}
I can add any code or ressource if needed just tell me on the comments.
You're never really returning the ViewHolder you inflated.
You shouldn't call super when the view is null. You should inflate it, get the child views, populate them and finally return the inflated root view.
Take a look at the docs to learn more about this process.
Try to write the adapter like this:
public class EarthQuakeAdapter extends ArrayAdapter<Earthquake> {
// ...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
Earthquake currentEarthquake = getItem(position);
TextView magnitude = (TextView) listItemView.findViewById(R.id.magnitude);
// Get the version name from the current AndroidFlavor object and
// set this text on the name TextView
magnitude.setText(Earthquake.getmMagnitude());
// Find the TextView in the list_item.xml layout with the ID version_number
TextView place = (TextView) listItemView.findViewById(R.id.Place); // Get the version number from the current AndroidFlavor object and
// set this text on the number TextView
place.setText(Earthquake.getMplace());
// Find the ImageView in the list_item.xml layout with the ID list_item_icon
TextView date = (TextView) listItemView.findViewById(R.id.Date);
date.setText(Earthquake.getmDate());
// Get the image resource ID from the current AndroidFlavor object and
// set the image to iconView
// Return the whole list item layout (containing 2 TextViews and an ImageView)
// so that it can be shown in the ListView
return listItemView;
}
}
You can read more about smooth scrolling here on android's training page.
And as an option, you could switch to RecyclerView, you can read more about it here.
You shouldn't need to call super.getView(...) in the overridden getView function, and you're passing in an invalid resource ID. Simply remove that line, since you're not using its return value anyway:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if(listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
...
}
Related
I have a dynamic adapter that fills up a listview with textviews with values read from a JSON file, here is an example ( https://imgur.com/a/w9CHzxX ). Now I need to gather the user input from those fields and use it in a later part of my application, but my question is. when i generate textviews like that they all have the same ID right? so how can i specificly gather the user input of lets say the 2nd textview?
Adapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {if (convertView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.layout_question_textfield, null, true);
---> holder.editText = (AutoCompleteTextView) convertView.findViewById(R.id.edt);
---> holder.editTitel = (Button) convertView.findViewById(R.id.btn);
convertView.setTag(holder);
}
else {...}
holder.editText.setHint(HintArrayList.get(position).getEditTextValue());
ID is an attribute of a view that scope of this attribute is limited by the inflated view group that includes this view.
for example if we have this xml file (item_view.xml):
<LinearLayout
...>
<TextView
...
android:id="#+id/textView_itemVew"/>
</LinearLayout>
and then we inflate this file several times (maybe in an adapter class) as below:
View item1 = inflater.inflate(R.layout.item_view, null,true);
View item2 = inflater.inflate(R.layout.item_view, null,true);
View item3 = inflater.inflate(R.layout.item_view, null,true);
now we can access the TextView view by it's ID but we should use the view group of this TextView to find it.
//Id's are the same but view groups no!
TextView editText_of_item1 = item1.findViewById(R.id.editText_itemVew);.
TextView editText_of_item2 = item2.findViewById(R.id.editText_itemVew);
TextView editText_of_item3 = item3.findViewById(R.id.editText_itemVew);
.
.
.
in your case you can add each EditText to a list to access it after whole list inflated ... like this:
List<EditText> editTextList = new ArrayList<>();
public View getView(int position,View view,ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View itemView = inflater.inflate(R.layout.item_view, null,true);
EditText itemEditText = (EditText) itemView.findViewById(R.id.editText);
editTextList.add(itemEditText);
return itemView;
};
there is useful example in javaTpoint website for you.
I am trying to implement a Newsfeed-type layout with multiple feed items.
The newsfeed item would have a certain layout when collapsed, and this layout would be replaced by an 'exploded' version, when the item is clicked.
I accomplished this by using a ListView of custom items. The custom item XML layout file has a ViewStub which is what I used to change the layout back and forth.
Now, though, I wanted to 'migrate' the layout over to RecyclerView, and to also follow a ViewHolder design pattern.
The latter is what I have tried first, and I'm running into all sorts of problems.
My approach has been as follows:
Get reference to collapsed layout (events_list_item_content) and expanded layout (events_list_item_selected_content);
Get reference to a simple layout resource file to be set as the ViewStub layout (view_stub_layout).
Get ViewStub reference, set its layout (view_stub_layout) inflate, and add the collapsed layout view to this layout (when first creating the feed, all of its items are going to be collapsed).
(After initialisation, when an item is clicked) Remove previous view (layout) from the ViewStubLayout, add the other type of layout.
Here is my custom adapter class:
public class FeedRecyclerAdapter extends BaseAdapter {
public class ViewHolder {
View inflatedViewStub1;
ViewStub viewStub;
LinearLayout viewStubLayout;
LinearLayout listItemContent, listItemContentSelected;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final FeedItem item = feedItems.get(position);
final ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = inflater.inflate(R.layout.events_list_item_content_new_container, parent, false);
View view = null;
view = inflater.inflate(R.layout.events_list_item_content, null);
viewHolder.listItemContent = (LinearLayout) view.findViewById(R.id.events_list_item_content);
view = inflater.inflate(R.layout.events_list_item_selected_content, null);
viewHolder.listItemContentSelected = (LinearLayout) view.findViewById(R.id.events_list_item_content_selected);
view = inflater.inflate(R.layout.view_stub_layout, null);
viewHolder.viewStubLayout = (LinearLayout) view.findViewById(R.id.view_stub_layout);
viewHolder.viewStub = (ViewStub) convertView.findViewById(R.id.list_item_feed);
(viewHolder.viewStubLayout).addView(viewHolder.listItemContent);
viewHolder.viewStub.setLayoutResource(R.layout.view_stub_layout);
viewHolder.inflatedViewStub1 = viewHolder.viewStub.inflate();
convertView.setTag(viewHolder);
} else viewHolder = (ViewHolder) convertView.getTag();
if (item.getExploded()) {
viewHolder.viewStubLayout.removeAllViews();
viewHolder.viewStubLayout.addView(viewHolder.listItemContentSelected);
} else {
viewHolder.viewStubLayout.removeAllViews();
viewHolder.viewStubLayout.addView(viewHolder.listItemContent);
}
return convertView;
}
However, when testing, the page where the Newsfeed is supposed to appear is blank.
ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
stub.setLayoutResource(layoutId);
stub.inflate(); // inflate 1st layout
ll.removeAllViews(); // remove previous view, add 2nd layout
ll.addView(LayoutInflater.from(context).inflate(secondLayoutId, ll, false));
Android ViewStub change layouts programatically
i'm trying to set textView in custom row view of listView like below but the app crashes returning null pointer exception
TextView txtrow = (TextView) getListView().getChildAt(i).findViewById(R.id.text11);
txtrow.setText("text");
but when i put it under setOnClickListener it works
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView txtrow = (TextView) getListView().getChildAt(i).findViewById(R.id.text11);
txtrow.setText("text");
}
});
You should be doing this inside your ListView's adapter. Whatever data you are using the back your adapter should contain the text you want so that you can set it on the appropriate TextView when you actually create the row view in getView().
It's important to note that getChildAt(index) returns the child at the given index from the ListView's current children. In other words, getChildAt(0) does not necessarily give you the list item at position 0. The user may have scrolled the list so that it now shows data from positions 10 through 15 (for example), in which case getChildAt(0) gives you the view for position 10, not position 0.
To set text in custom row in listview
Please follow the following points
1. custom arrayadapter by extending Arrayadpater (for simple)
2. and overwrite getview as following
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.label);
textView.setText(values[position]);
return rowView;
}
3. and set the adapter to the listview
And for more detial please refer this site
[http://www.vogella.com/tutorials/AndroidListView/article.html][1]
I have a listview that uses a customadapter based on the baseadapter. The listview populates ok using external data and I can pick up the click events and know which item has been selected.
I'm having a problem updating the clicked item's views, like TextView and ViewFlipper.
Do I have to update something via the listview or is it via the adapter. I've tried things like the following;
View test = (View)adapter.getView(pos, null, myListView);
ViewFlipper temp = (ViewFlipper)test.findViewById(R.id.flipholder);
temp.showNext();
TextView temp2 = (TextView)test.findViewById(R.id.filmtitle);
temp2.setText("Hello World");
Which results in the viewfliper flipping the first and third item or second and fourth and the text not updating at all.
Any ideas?
Cheers
Try this pattern in getView:
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
static class ViewHolder {
TextView text;
ImageView icon;
}
}
Can someone tell me what the convertView parameter is used for in the getView() method of the Adapter class?
Here is a sample code take from here:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
Order o = items.get(position);
if (o != null) {
TextView tt = (TextView) v.findViewById(R.id.toptext);
TextView bt = (TextView) v.findViewById(R.id.bottomtext);
if (tt != null) {
tt.setText("Name: "+o.getOrderName()); }
if(bt != null){
bt.setText("Status: "+ o.getOrderStatus());
}
}
return v;
}
What should we pass via convertView?
What I've found, take from here:
Get a View that displays the data at the specified position in the
data set. You can either create a View manually or inflate it from an
XML layout file. When the View is inflated, the parent View (GridView,
ListView...) will apply default layout parameters unless you use
inflate(int, android.view.ViewGroup, boolean) to specify a root view
and to prevent attachment to the root.
Parameters
position -- The position of the item within the adapter's data set of the item whose view we want.
convertView -- The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before
using. If it is not possible to convert this view to display the
correct data, this method can create a new view.
parent -- The parent that this view will eventually be attached to Returns
returns -- A View corresponding to the data at the specified position.
You shouldn't be calling that method by yourself.
Android's ListView uses an Adapter to fill itself with Views. When the ListView is shown, it starts calling getView() to populate itself. When the user scrolls a new view should be created, so for performance the ListView sends the Adapter an old view that it's not used any more in the convertView param.