Android: how to use BaseAdapter class without having a nullpointerexception - java

I understand that many of you are already fed up with the nullpointerexception-related questions, so I thought again and again whether or not to ask this question. I read up the following short code for an hour, and I still cannot figure out why the nullpointerexception is thrown..
Here is the ImageAdapter class..
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
public ImageAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mContext = context;
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mInflater.inflate(R.layout.dialog_addprofile, null);
convertView.setLayoutParams(new GridView.LayoutParams(90, 90));
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.categoryText);
holder.icon = (ImageView) convertView.findViewById(R.id.categoryimage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setAdjustViewBounds(true);
holder.icon.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.icon.setPadding(8, 8, 8, 8);
holder.title.setText(categoryContent[position]);
holder.icon.setImageResource(mThumbIds[position]);
return convertView;
}
class ViewHolder {
TextView title;
ImageView icon;
}
private Integer[] mThumbIds = {
android.R.drawable.ic_menu_gallery, android.R.drawable.ic_menu_camera
};
private String[] categoryContent = {
"Gallery", "Camera"
};
}
And here's the part of the logcat.
java.lang.NullPointerException
at com.marshall.thequizshow.ui.adapter.ImageAdapter.getView(ImageAdapter.java:56)
According to the logcat, the end part below the if-else statement in the getView method seems to have the problem. I tried really hard to figure out what should be fixed, but I'm still lost. Somebody please help me?

Add this line in your constructor
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

Related

Holder vs RecylerView.ViewHolder

I have ListView with Adapter, and also use holder. but later I read about recyclerView.ViewHolder and now confused, Is it different with the one I've been using right now? I mean for the optimization purpose, I want to know if using holder only is not good enough without using recyclerView.
public class NewsAdapter extends ArrayAdapter<News> {
Context context;
List<News> myList;
public NewsAdapter(Context context, int resource, List<News> objects) {
super(context, resource, objects);
this.context = context;
this.myList = objects;
}
#Override
public News getItem(int position) {
if(myList != null)
return myList.get(position);
return null;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_news, null);
holder = new NewsAdapter.Holder();
holder.title = (TextView)convertView.findViewById(R.id.textViewTitle);
holder.datePosted = (TextView)convertView.findViewById(R.id.textViewDate);
holder.imageView = (ImageView)convertView.findViewById(R.id.imageViewThumbnailpic);
convertView.setTag(holder);
}else{
holder = (Holder)convertView.getTag();
}
News news = getItem(position);
holder.title.setText(news.getTitle());
holder.datePosted.setText(news.getDatePost());
Picasso.with(context)
.load(news.getImgUrl())
.placeholder(R.drawable.coin25)
.error(R.drawable.hnbspic)
.into(holder.imageView);
return convertView;
}
private class Holder{
ImageView imageView;
TextView title;
TextView datePosted;
}
}
It's better to use Recyclerview because it has been optimized for various scenarios and not just for View holder pattern like it give the option for determining how your item should be laid out or like what should be the animation or custom drawing in each item.You can read more this medium post

How to imitate CustomListAdapter using variable <objects>

I am trying to implement a customlistadapter for a small project of mine. I basically want ask java to use the appropriate class to inflate the view. I have here first:
public class slide {
public class video {
VideoView videoOfTheDay;
//Purpose of this constructor
public video(VideoView videoOfTheDay) {
this.videoOfTheDay = videoOfTheDay;
}
public VideoView getVideoOfTheDay() {
return videoOfTheDay;
}
}
public class blog {
ImageView imageOfTheDay;
TextView messageOfTheDay;
public blog(ImageView imageOfTheDay, TextView messageOfTheDay) {
this.imageOfTheDay = imageOfTheDay;
this.messageOfTheDay = messageOfTheDay;
}
public ImageView getImageOfTheDay() {
return imageOfTheDay;
}
public TextView getMessageOfTheDay() {
return messageOfTheDay;
}
}
public class advertisement {
ImageView ImageViewAd1;
ImageView ImageViewAd2;
public advertisement(ImageView imageViewAd1, ImageView imageViewAd2) {
this.ImageViewAd1 = imageViewAd1;
this.ImageViewAd2 = imageViewAd2;
}
public ImageView getImageViewAd1() {
return ImageViewAd1;
}
public ImageView getImageViewAd2() {
return ImageViewAd2;
}
}
}`
I have listed all the classes within a superclass slide because I wasn't able to accomplish no errors without them being grouped. From there I went to ask Java to look within itself and determine the appropriate class to use to populate the element:
class CustomListAdapter extends BaseAdapter {
private ArrayList<slide> customVariableDisplay;
private LayoutInflater layoutInflater;
public CustomListAdapter(Context context, ArrayList<slide>customVariableDisplay) {
this.customVariableDisplay = customVariableDisplay;
layoutInflater = LayoutInflater.from(context);
}
public int getCount() {
return customVariableDisplay.size();
}
public Object getItem(int position) {
return customVariableDisplay.get(position);
}
public long getItemId(int position) {
return position;
}
// If the element of the slide is a video -- then the getView will return...
if(slide==slide.video){
public View getView ( int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.act_layout, null);
holder = new ViewHolder();
holder.slide.video = (VideoView) convertView.findViewById(R.id.videolayout);
}
else{
holder = (ViewHolder)convertView.getTag();
}
holder.video.setVideoResource(customVariableDisplay.get(position).getVideoOfTheDay());
}
return convertView;
}
// If the element is a 'blog' then --- then the getView will return...
else if(slide==slide.blog){
public View getView ( int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.act_layout, null);
holder = new ViewHolder();
holder.slide.blog.message = (TextView) convertView.findViewById(R.id.messageInLayout);
holder.slide.blog.image = (ImageView) convertView.findViewById(R.id.imageInLayout);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
//Can write to getClass() for either?
//Ex: holder.(setImageResource(cVD) || setText(cVD)).getClass ??
holder.image.setImageResource(customVariableDisplay.get(position).getImageofTheDay());
holder.message.setText(customVariableDisplay.get(position).getMessageOfTheDay());
}
return convertView;
}
//Else if the element of the slide is an 'advertisement' then the getView will return...
else if (slide==slide.advertisement){
public View getView ( int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.act_layout, null);
holder = new ViewHolder();
holder.slide.advertisement.imagead1 = (ImageView)convertView.findViewById(R.id.imageAdOneInAdvertisementLayout);
holder.slide.blog.image = (ImageView)convertView.findViewById(R.id.imageAdTwoInAdvertismentLayout);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.imagead1.setImageResource(customVariableDisplay.get(position).getImageViewAd1());
holder.imagead2.setImageResource(customVariableDisplay.get(position).getImageViewAd2());
}
return convertView;
}
else{
//Throw a final View exception for unprecedented errors!!
}
}
}`
I am stuck with what to a way to ask Java what class is it inside the if statements. // If this slide comprises the class blog... etc. ANY HELP APPRECIATED! THANKS!
You can declare one variable slideType in your adapter and pass it to your adapter constructor and based on that value inflate your layout in onBindViewHolder(), onCreateViewHolder()
int slideType;
public CustomListAdapter(Context context, ArrayList<slide>customVariableDisplay, int slideType) {
this.slideType = slideType;
}
and also define three separate method in your adapter to pass your list so that you can bind your data.
Does this ListView show a mix of video, blog etc.. if yes then you need use below checking.
if(null != slide.video){
// add code for video
}
else if(null != slide.blog){
// add code for blog
}
else if (null != slide.advertisement){
// add code for advertisement
}
Also you need to set null for blog and advertisement in slide object or don't initialize them in case the item you want to show is video

Android - Images changing on GridView when scrolling

I am trying to create a custom adapter for a shop element in my Android app but every time I scroll down the list the images seem to change their position, I have had a look around on here already but suggestions that I have found and tried have been to no avail.
Each item has a title, an image (being loading via an AsyncTask or retrieved from the LRUCache) and a price of the item below is the code I use to generate the adapter.
public class ShopAdapter extends BaseAdapter {
public Context context;
public ArrayList<ShopItem> shopItemList;
public ImageCache imageCache;
String imageToLoad;
Bitmap shopImage;
public ShopAdapter(Context context, ArrayList<ShopItem> shopItemList) {
this.context = context;
this.shopItemList = shopItemList;
imageCache = new ImageCache(this.context);
}
#Override
public int getCount() {
return shopItemList.size();
}
#Override
public Object getItem(int position) {
return shopItemList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView == null){
LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.shop_list, null);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.textView3);
holder.image =(ImageView) convertView.findViewById(R.id.imageView);
holder.price = (TextView) convertView.findViewById(R.id.textView4);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.title.setText(shopItemList.get(position).getTitle());
shopImage = imageCache.getBitmapFromMemoryCache(shopItemList.get(position).getImage());
if(shopImage != null) {
holder.image.setImageBitmap(shopImage);
} else {
new LoadImage(context, holder.image).execute(imageToLoad);
}
holder.price.setText(shopItemList.get(position).getPrice());
return convertView;
}
static class ViewHolder {
TextView title;
ImageView image;
TextView price;
}
}
Any help would be very much appreciated!

Android Checkbox in Listview selecting automatically

in my android application I am displaying the contact list of phone in a list view and a check box in each row for selecting contacts. But when I am selecting a particular row about tenth row is also getting selected automatically. I am giving my code below, if any one knows please help..
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
final ViewHolder mHolder;
if (convertView == null)
{
// gridView = new View(context);
// get layout from mobile.xml
//gridView = inflater.inflate(R.layout.contact, null);
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
));
}
else
{
mHolder = (ViewHolder) convertView.getTag();
mHolder.textSelector.setOnCheckedChangeListener(null);
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textSelector.setFocusable(false);
return convertView;
}
private class ViewHolder {
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
Well Thats because ViewHolder will recycle the Views everytime you Scroll
i suggest you to Use onCLick on ListItem instead checkbox
To overcome this Declare a SparseBooleanArray
SparseBooleanArray sba=new SparseBooleanArray();//this should be global
Then set the items checked state as soon as you render it
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
mHolder.textSelector.setChecked(sba.get(position));
Then write a onClickListener to you convertView and check it manually
convertView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
mHolder.textSelector.setChecked(isChecked);
sba.put(position,isChecked); //storing the state
}
}
);
**Well Now the sba has list items checked and you can use that for further Actions**
# Jocheved... edit your code like this...
public class ContactsAdapter extends BaseAdapter
{
private Context context;
private ArrayList<Contact> contacts;
SparseBooleanArray sba=new SparseBooleanArray();
public ContactsAdapter(Context context, ArrayList<Contact> contacts)
{
this.context = context;
this.contacts = contacts;
}
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ViewHolder mHolder;
if (convertView == null)
{
convertView = inflater.inflate(R.layout.contact, null);
mHolder = new ViewHolder();
mHolder.textName =(TextView) convertView.findViewById(R.id.name);
mHolder.textMobile =(TextView) convertView.findViewById(R.id.mobile);
mHolder.textSelector =(CheckBox) convertView.findViewById(R.id.selected);
convertView.setTag(mHolder);
}
else
{
mHolder = (ViewHolder) convertView.getTag();
}
mHolder.textMobile.setText(contacts.get(position).getMobile());
mHolder.textName.setText(contacts.get(position).getName());
mHolder.textName.setSelected(true);
mHolder.textSelector.setChecked(sba.get(position));
mHolder.textSelector.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
if(mHolder.textSelector.isChecked())
{
sba.put(position, true);
}
else
{
sba.put(position, false);
}
}
});
return convertView;
}
private class ViewHolder
{
private TextView textMobile,textName;
private CheckBox textSelector;
}
#Override
public int getCount() {
return contacts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}

grid view scrolling issue?

I making a gridview that is made of a text and under it an image and everything is working fine but the problem is that when I scroll, the images gets repeated, so any tips on how I could solve this problem
here is my adapter:
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private final String[] mobileValues;
public CustomGridAdapter(Context context, String[] mobileValues) {
this.context = context;
this.mobileValues = mobileValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.heartless_gridview_design, null);
// set value into textview
TextView textView = (TextView) gridView
.findViewById(R.id.heartless_name);
textView.setText(mobileValues[position]);
// set image based on selected text
ImageView imageView = (ImageView) gridView
.findViewById(R.id.heartless_image);
String mobile = mobileValues[position];
if (mobile.equals("Shadow")) {
imageView.setImageResource(R.drawable.shadow);
} else if (mobile.equals("Soldier")) {
imageView.setImageResource(R.drawable.soldier);
} else if (mobile.equals("Large Body")) {
imageView.setImageResource(R.drawable.large_body);
} else if (mobile.equals("Silver Rock")) {
imageView.setImageResource(R.drawable.silver_rock);
} else if (mobile.equals("Emerald Blues")) {
imageView.setImageResource(R.drawable.emerald_blues);
} else {
}
} else {
gridView = (View) convertView;
}
return gridView;
}
#Override
public int getCount() {
return mobileValues.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
}
please if you know how to fix this please tell me how.
so far I understood you should use viewholder pattern and
every time when getView method calls check if viewholder is null initialize it otherwise do nothing just return view..
http://developer.android.com/training/improving-layouts/smooth-scrolling.html#ViewHolder
and good example here - http://java.dzone.com/articles/android-listview-optimizations

Categories

Resources