I try create multi ListView but I have java.lang.NullPointerException. It seems to be alright.
Main:
for(int i = 0; i < 10; i++) {
ActivityObject ao = new ActivityObject();
if(i%2 == 0) {
ao.setType("0");
ao.setTitle("Im null");
} else {
ao.setType("1");
ao.setTitle("Im one");
}
dataActivity.add(ao);
}
ActivityAdapter adapter = new ActivityAdapter(getApplicationContext(), dataActivity);
listActivity.setAdapter(adapter);
Super Adapter
public class ActivityAdapter extends ArrayAdapter {
private Context context;
private ArrayList<ActivityObject> object;
LayoutInflater vi;
public ActivityAdapter(Context context, ArrayList<ActivityObject> object) {
super(context, 0, object);
this.context = context;
this.object = object;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null) {
if(object.get(position).equals("0")) {
convertView = vi.inflate(R.layout.p_activity_detected, null);
holder.textActivity = (TextView) convertView.findViewById(R.id.detected_text);
}
if(object.get(position).equals("1")) {
convertView = vi.inflate(R.layout.p_activity_people, null);
holder.textPeople = (TextView) convertView.findViewById(R.id.people_text);
}
holder = new ViewHolder();
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//set text
if(object.get(position).getType().equals("0")) {
holder.textActivity.setText(object.get(position).getTitle());
}
if(object.get(position).getType().equals("1")) {
holder.textPeople.setText(object.get(position).getTitle());
}
return convertView;
}
static class ViewHolder {
public TextView textActivity;
public TextView textPeople;
}
}
Error
FATAL EXCEPTION: main
java.lang.NullPointerException
at adapters.ActivityAdapter.getView(ActivityAdapter.java:54)
this is line
convertView.setTag(holder);
Replace yours adapter with these code
public class ActivityAdapter extends ArrayAdapter {
private Context context;
private ArrayList<ActivityObject> object;
LayoutInflater vi;
ViewHolder holder;
public ActivityAdapter(Context context, ArrayList<ActivityObject> object) {
super(context, 0, object);
this.context = context;
this.object = object;
vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
holder = new ViewHolder();;
if(convertView == null) {
if(object.get(position).equals("0")) {
convertView = vi.inflate(R.layout.p_activity_detected, null);
holder.textActivity = (TextView) convertView.findViewById(R.id.detected_text);
}
if(object.get(position).equals("1")) {
convertView = vi.inflate(R.layout.p_activity_people, null);
holder.textPeople = (TextView) convertView.findViewById(R.id.people_text);
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//set text
if(object.get(position).getType().equals("0")) {
holder.textActivity.setText(object.get(position).getTitle());
}
if(object.get(position).getType().equals("1")) {
holder.textPeople.setText(object.get(position).getTitle());
}
return convertView;
}
static class ViewHolder {
public TextView textActivity;
public TextView textPeople;
}
}
Move your holder on top. I think it will works. In my opinion you also have to use else statement.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
Log.d("object.get(position) = ", object.get(position));
if(object.get(position).equals("0")) {
convertView = vi.inflate(R.layout.p_activity_detected, null);
holder.textActivity = (TextView) convertView.findViewById(R.id.detected_text);
}
else if(object.get(position).equals("1")) {
convertView = vi.inflate(R.layout.p_activity_people, null);
holder.textPeople = (TextView) convertView.findViewById(R.id.people_text);
}
else{
//set defualt holder.textPeople here
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//set text
if(object.get(position).getType().equals("0")) {
holder.textActivity.setText(object.get(position).getTitle());
}
if(object.get(position).getType().equals("1")) {
holder.textPeople.setText(object.get(position).getTitle());
}
return convertView;
}
There is no guarantee in your code that convertView will not be null:
if(convertView == null) {
if(object.get(position).equals("0")) {
convertView = vi.inflate(R.layout.p_activity_detected, null);
holder.textActivity = (TextView) convertView.findViewById(R.id.detected_text);
}
if(object.get(position).equals("1")) {
convertView = vi.inflate(R.layout.p_activity_people, null);
holder.textPeople = (TextView) convertView.findViewById(R.id.people_text);
}
holder = new ViewHolder();
convertView.setTag(holder);
If none of the conditions above hold true, then convertView will still be null.
Are you sure the conditions are exactly what you want to do?
According to your declaration
private ArrayList<ActivityObject> object;
object is a list of ActivityObject, but you are comparing them with the strings "0" and "1" in
object.get(position).equals("0"))
...
object.get(position).equals("1"))
Maybe you want to cast them into ActivityObject and the compare the field in type with the strings?
Related
I'm having a ListView with a custom ArrayAdapter. The problem is that I cannot hide (setVisibility(View.GONE)) TextView in some elements of choice. Here is a minimized-readable summary part of my code:
public class ListViewAdapter extends ArrayAdapter<ItemModel> {
private int listItemLayout;
static class ViewHolder {
private TextView description;
}
public ListViewAdapter(Context context, int layoutId, List<ItemModel> itemList) {
super(context, layoutId, itemList);
this.listItemLayout = layoutId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemModel item = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(listItemLayout, parent, false);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.description = convertView.findViewById(R.id.text_desription);
viewHolder.description.setText(item.getDescription());
if (TextUtils.isEmpty(item.getDescription())) {
viewHolder.description.setVisibility(View.GONE);
}
return convertView;
}
}
What am I doing wrong here? How can I hide a view inside item in ListView if its content String is empty?
Add else part of if condition to change visibility from GONE to VISIBLE as in below code.
public class ListViewAdapter extends ArrayAdapter {
private int listItemLayout;
static class ViewHolder {
private TextView description;
}
public ListViewAdapter(Context context, int layoutId, List itemList) {
super(context, layoutId, itemList);
this.listItemLayout = layoutId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemModel item = getItem(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(listItemLayout, parent, false);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.description = convertView.findViewById(R.id.text_desription);
viewHolder.description.setText(item.getDescription());
if (TextUtils.isEmpty(item.getDescription())) {
viewHolder.description.setVisibility(View.GONE);
}else{
viewHolder.description.setVisibility(View.VISIBLE);
}
return convertView;
}
}
OR try if (item.getDescription()==null || item.getDescription().trim().length() == 0)
instead of if (TextUtils.isEmpty(item.getDescription()))
Check any white space should not be in your text. Try this-
if (TextUtils.isEmpty(item.getDescription().trim()) ||item.getDescription().trim().length()==0 ) {
viewHolder.description.setVisibility(View.GONE);
}
else{
viewHolder.description.setVisibility(View.VISIBLE);
}
I have an arraylist that needs to be updated using the adpater. I dont have any textviews for it. Here is my code -
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
The setData method will receive an arraylist and I need to populate the view with my Arraylist. I am using a viewHolder. How do I achieve this?
Try like this:
public class MyAdapter extends BaseAdapter {
private LayoutInflater inflater = null;
private ArrayList<MyClass> favouriteMessageList;
private MyAdapter(Activity activity, ArrayList list) {
favouriteMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
MyClass favouriteMessage = favouriteMessageList.get(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.messaging_favorites_layout, null);
viewHolder = new ViewHolder();
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//Update Your Views Here
return convertView;
}
#Override
public int getCount() {
if (favouriteMessageList != null) return favouriteMessageList.size();
return 0;
}
public void setData(ArrayList<MyClass> data) {
favouriteMessageList = data;
notifyDataSetChanged();
}
}
I have a custom adapter class for a listview and I want to be able to access the content of a specific row by clicking a button on it. I tried to create a ViewHolder, but I get a NPE error when I try to click it.
static class ViewHolder {
TextView camera;
TextView players;
TextView max_players;
ImageView privata;
Button Buton;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
String variabile[] = getItem(position).split("\\s+");
LayoutInflater linflater = LayoutInflater.from(getContext());
View customView = linflater.inflate(R.layout.custom_row, parent, false);
final ViewHolder holder = new ViewHolder();
holder.camera = (TextView) customView.findViewById(R.id.Nume);
holder.players = (TextView) customView.findViewById(R.id.players);
holder.max_players = (TextView) customView.findViewById(R.id.max_players);
holder.privata = (ImageView) customView.findViewById(R.id.privata);
holder.Buton = (Button) customView.findViewById(R.id.Buton);
holder.camera.setText(variabile[0]);
if (!variabile[1].equals("true")) {
parola = false;
holder.privata.setVisibility(View.INVISIBLE);
}
holder.players.setText(variabile[2]);
holder.max_players.setText(variabile[3]);
room_id = variabile[4];
nume = variabile[5];
holder.Buton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
hash = new HashMap<String, String>();
hash.put("name", nume);
hash.put("room", room_id);
if (intra) {
holder.Buton.setText("Iesi");
site = siteul + "/join";
intra = false;
} else {
holder.Buton.setText("Intra");
site = siteul + "/leave";
intra = true;
}
new ATask().execute(site);
}
});
return customView;
}
When using the ViewHolder pattern, you should check if the convertView in null or has been created before, in the getView method, and after that use setTag and getTag methods. like this :
if (convertView == null)
{
LayoutInflater linflater = LayoutInflater.from(getContext());
convertView = linflater.inflate(R.layout.your_list_item_view, parent, false);
viewHolder.textView = (TextView)convertView.findViewById([the id]);
.
.
.
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
You need to check if the convertView is null so it is already has been visited or not then store the holder in tag Like
ViewHolder holder;
if (convertView == null) {
LayoutInflater linflater = LayoutInflater.from(getContext());
holder = linflater.inflate(R.layout.custom_row, parent, false);....
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}//Common code
I have
public class MainActivity extends FragmentActivity
I wrote Loader class which implements AsyncResponse:
public class Loader implements AsyncResponse {
public Activity contextActivity;
Loader(Activity context) {
this.contextActivity = context;
}
Class "Loader" has method "DrawTabInfo" which calling from AsyncResponse callback.
public void drawTabInfo(String jsonBlob, int tabId)
{
JSONObject dataJsonObj;
PullToRefreshListView list = null;
try {
dataJsonObj = new JSONObject(jsonBlob);
JSONArray jsonData = dataJsonObj.getJSONArray("steals");
ArrayList<JSONObject> data = new ArrayList<JSONObject>();
for (int i=0;i<jsonData.length();i++){
data.add(jsonData.getJSONObject(i));
}
Adapter adapter = new Adapter(contextActivity, data);
LayoutInflater inflater = LayoutInflater.from(contextActivity);
if (tabId == 0) {
View view = inflater.inflate(R.layout.listviewlayout, null, false);
list = (PullToRefreshListView) view.findViewById(R.id.listView);
}
if (tabId == 1) {
View view = inflater.inflate(R.layout.listviewlayout2, null, false);
list = (PullToRefreshListView) view.findViewById(R.id.listView2);
}
list.setAdapter(adapter);
adapter.setNotifyOnChange(true);
Log.d("COUNT") shows - "4", what means array is built fine.
public class Adapter extends ArrayAdapter<JSONObject> {
private final Activity context;
private final ArrayList<JSONObject> profiles;
public String header;
public String preText;
public String imageURL;
static class ViewHolder {
public TextView header;
public ImageView image;
public TextView preText;
public LinearLayout linearItemLayout;
}
public Adapter(Activity context, ArrayList<JSONObject> array) {
super(context, R.layout.tab1_list_layout, array);
Log.d("ADAPTER", "SETTING ADAPTER");
this.context = context;
this.profiles = array;
Log.d("COUNT", "" + profiles.size());
}
#Override
public int getCount()
{
return profiles.size();
}
My getView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
Log.i("GetView Log", "Adapters GetView hasbeen called");// thats never calling
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.tab1_list_layout, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.linearItemLayout = (LinearLayout) rowView.findViewById(R.id.linearItemLayout);
viewHolder.header = (TextView) rowView.findViewById(R.id.itemHeader);
viewHolder.image = (ImageView) rowView.findViewById(R.id.itemPreImage);
viewHolder.preText = (TextView) rowView.findViewById(R.id.itemPreText);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
JSONObject item = null;
try {
item = profiles.get(position);
header = item.getString("header");
preText = item.getString("previewText");
imageURL = item.getString("previewImageUrl");
} catch (JSONException e) {
e.printStackTrace();
}
Log.d("ADAPTER LOG", header);
holder.header.setText(header);
holder.preText.setText(preText);
int headerHeight = (int) Math.round(header.length() * 1.5);
holder.linearItemLayout.setMinimumHeight(40 + headerHeight + preText.length());
Picasso.with(context).setIndicatorsEnabled(true);
Picasso.with(context).load(imageURL).resize(140,100).into(holder.image);
return rowView;
}
In MainActivity i calling, where "this" = MainActivity;
Loader loader = new Loader(this);
loader.loadTabInfo(0);
Method getView never calling. What I'am doing wrong?
UPD:
Solved:
public void drawTabInfo(String jsonBlob, int tabId)
{
JSONObject dataJsonObj;
PullToRefreshListView list = null;
try {
dataJsonObj = new JSONObject(jsonBlob);
JSONArray jsonData = dataJsonObj.getJSONArray("steals");
ArrayList<JSONObject> data = new ArrayList<JSONObject>();
for (int i=0;i<jsonData.length();i++){
data.add(jsonData.getJSONObject(i));
}
Adapter adapter = new Adapter(contextActivity, data);
//LayoutInflater inflater = LayoutInflater.from(contextActivity);
if (tabId == 0) {
//View view = inflater.inflate(R.layout.listviewlayout, null, false);
list = (PullToRefreshListView) contextActivity.findViewById(R.id.listView);
Your code is fine .. just you need a little bit change in get view method
add a return statement.. like return rowView;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
Log.d("GETVIEaW", "GETVIEW");
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.tab1_list_layout, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.linearItemLayout = (LinearLayout) rowView.findViewById(R.id.linearItemLayout);
viewHolder.header = (TextView) rowView.findViewById(R.id.itemHeader);
viewHolder.image = (ImageView) rowView.findViewById(R.id.itemPreImage);
viewHolder.preText = (TextView) rowView.findViewById(R.id.itemPreText);
rowView.setTag(viewHolder);
}
else{
viewHolder = (ViewHolder) rowView.getTag();
}
viewHolder.preText.setText("Type your name");
return rowView;
}
Are you sure that Log.d() is not called? You may want to change logging scope, usually default scope is info and it doesn't show debug messages. You can try to use Log.i() or change scope.
Try posting your adapter.setNotifyOnChange(true); to handler. Follow this link
How can i use the method getChildFragmentManager() in a custom adapter that extends ArrayAdapter<> ?
Here's my code if you need to see it:
MyAdapter.java:
public class MyAdapter extends ArrayAdapter<Content> {
Context context;
List<Content> myList;
public static final String pattern = "(?<=watch\\?v=|/videos/|embed\\/)[^#\\&\\?]*";
public MyAdapter(Context context, int resource, List<Content> objects) {
super(context, resource, objects);
this.context = context;
this.myList = objects;
}
#Override
public int getCount() {
if (myList != null)
return myList.size();
return 0;
}
#Override
public Content getItem(int position) {
if (myList != null)
return myList.get(position);
return null;
}
#Override
public long getItemId(int position) {
if (myList != null)
return myList.get(position).hashCode();
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
holder = new Holder();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item, null);
holder.contId = (TextView) convertView.findViewById(R.id.content_id);
holder.contType = (TextView) convertView.findViewById(R.id.type);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.txtTeaser = (TextView) convertView.findViewById(R.id.teaser);
holder.imageView = (ImageView) convertView.findViewById(R.id.cover_photo);
holder.youTubeVideo = (FrameLayout) convertView.findViewById(R.id.youTube_frame);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
Content content = getItem(position);
holder.contId.setText(content.getId());
holder.contType.setText(content.getType());
holder.txtTitle.setText(content.getTitle());
holder.txtTeaser.setText(content.getTeaser());
Picasso.with(context).load(Uri.parse(content.getImageUrl())).into(holder.imageView);
if(content.getCoverVideo() != null && !content.getCoverVideo().equals("")){
String cover_video = content.getCoverVideo();
Pattern compiledPattern = Pattern.compile(pattern);
Matcher matcher = compiledPattern.matcher(cover_video);
if(matcher.find()){
cover_video = matcher.group();
}
Bundle youTubeBundle = new Bundle();
youTubeBundle.putString("link", cover_video);
FragmentManager manager = getChildFragmentManager(); // <------ Can't resolve method
FragmentTransaction transaction = manager.beginTransaction();
ArticleYouTubeFragment youtubeFragment = new ArticleYouTubeFragment();
youtubeFragment.setArguments(youTubeBundle);
transaction.replace(R.id.list_youTube_frame, youtubeFragment);
transaction.commit();
}
return convertView;
}
private class Holder {
TextView contId;
TextView contType;
TextView txtTitle;
TextView txtTeaser;
ImageView imageView;
FrameLayout youTubeVideo;
}
}
Thanks in advance.