I have tried adding the adapter in the onCreate() as well and it throws a null pointer exception with an error 'Attempt to invoke listVIew.setAdapter on a null object reference.
Here is the code where I use notifyDataSetChange() inside my Main Activity;
import static com.name.sample.Tab1.adapter;
public class Requests extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
Cursor c = myDB.rawQuery("SELECT * FROM requests", null);
int aIndex = c.getColumnIndex("name");
int bIndex = c.getColumnIndex("nick");
int cIndex = c.getColumnIndex("num");
name.clear();
nick.clear();
number.clear();
if (c.moveToFirst()){
do {
name.add(c.getString(aIndex));
nick.add(c.getString(bIndex));
number.add(c.getInt(cIndex));
} while (c.moveToNext());
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter.notifyDataSetChanged();
}
}
Here is my Tab1 code
Here is the code for the Adapter
public class Tab1 extends Fragment {
static ListView listNotifications;
final static ArrayList<String> name = new ArrayList<>();
static ArrayList<Integer> number = new ArrayList<>();
static ArrayList<String> nick = new ArrayList<>();
static ImageAdapter adapter;
public static class ImageAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
public ImageAdapter (Context context, String[] values) {
super(context, R.layout.list_with_icons, values);
this.context = context;
this.values = values;
}
#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.list_with_icons, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.textViewName);
ImageView imageView = (ImageView) rowView.findViewById(R.id.imagePicture);
textView.setText(values[position]);
// Change the icon for Windows and iPhone
return rowView;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1layout, container, false);
String[] nameString = new String[name.size()];
nameString = name.toArray(nameString);
adapter = new ImageAdapter (getActivity(), nameString);
listNotifications =(ListView)rootView.findViewById(R.id.listNotifications);
listNotifications.setAdapter(adapter);
return rootView;
}}
Try using: adapterClass.this.notifyDataSetChanged() in onPostExcecute()
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
InvitedAdapter.this.notifyDataSetChanged();
}
you have added a wrong adapter in the listview. it should be like this in onCreateView():
listNotifications.setAdapter(adapter);
Try this :)
Related
I'm new to Android and I'm still learning. Could You please help me?
I'm trying to set clickable List in ListFragment with custom ArrayAdapter. It works with normal ArrayAdapter but not with custom. Here is my CustomArrayAdapter class:
public class CustomListAdapter<T> extends ArrayAdapter<T> {
private List<Integer> imageIds;
private List<String> titleList;
private List<String> descriptionList;
private List<String> createdList;
private final Context activityContext;
private static final String DATE_FORMAT_8 = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_8);
public CustomListAdapter(#NonNull Context context, #NonNull List<T> objects) {
super(context, R.layout.row_layout, objects);
this.activityContext = context;
imageIds = new ArrayList<>();
titleList = new ArrayList<>();
descriptionList = new ArrayList<>();
createdList = new ArrayList<>();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View rowView = convertView;
if (convertView == null)
rowView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);
ImageView ivNote = rowView.findViewById(R.id.ivNote);
TextView tvTitle = rowView.findViewById(R.id.tvTitle);
TextView tvDescription = rowView.findViewById(R.id.tvDescription);
TextView tvCreated = rowView.findViewById(R.id.tvCreated);
ivNote.setImageResource(imageIds.get(position));
tvTitle.setText(titleList.get(position));
tvDescription.setText(descriptionList.get(position));
tvCreated.setText(createdList.get(position));
return rowView;
}
list setters etc
And here is my ListFragment class:
private List<TaskDTO> taskDTOS;
TasksItemSelected tasksItemSelected;
public interface TasksItemSelected {
void onTaskItemSelected(int index);
}
public TasksFragment() {
// Required empty public constructor
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
tasksItemSelected = (TasksItemSelected) context;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments() != null) {
taskDTOS = (List<TaskDTO>) getArguments().getSerializable("tasksList");
}
View view = inflater.inflate(R.layout.fragment_tasks, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (taskDTOS != null && taskDTOS.size() > 0) {
setListAdapter(getCustomListAdapter(getContext(),taskDTOS));
}
}
private CustomListAdapter getCustomListAdapter(Context activity, List<TaskDTO> taskDTOS) {
CustomListAdapter customListAdapter = new CustomListAdapter(activity, taskDTOS);
customListAdapter.setImageIds(taskDTOS);
customListAdapter.setTitleList(taskDTOS);
customListAdapter.setDescriptionList(taskDTOS);
customListAdapter.setCreatedList(taskDTOS);
return customListAdapter;
}
#Override
public void onListItemClick(#NonNull ListView l, #NonNull View v, int position, long id) {
super.onListItemClick(l, v, position, id);
tasksItemSelected.onTaskItemSelected(position);
}
}
When I set new ArrayAdapter, list items become clickable and new activity runs, but nothing happens when tapping list items in the above case.
I am making a simple Android list view app which will show some basic name, in list view. My app is stopping unexpectedly. The logcat is showing this error.
Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()'
on a null object reference.
CustomAdapter
public class CustomAdapter extends BaseAdapter {
Context context;
String animals[];
LayoutInflater inflater;
public CustomAdapter(Context applicationContext, String[] animals){
this.context = applicationContext;
this.animals = animals;
inflater = (LayoutInflater.from(applicationContext));
}
#Override
public int getCount() {
return animals.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflater.inflate(R.layout.listview, null);
TextView textView = (TextView) view.findViewById(R.id.tv);
textView.setText(animals[i]);
return null;
}
}
Main Activity
public class MainActivity extends AppCompatActivity {
ListView listView;
String animals[]= {"Dog", "Cat", "Humans", "Monkey", "Rat", "Snake", "Elephant", "Giraffe", "Deer", "Tiger", "Lion","Cow", "Pig", "Goat"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView =(ListView) findViewById(R.id.lv);
CustomAdapter customAdapter = new CustomAdapter(getApplicationContext(), animals);
listView.setAdapter(customAdapter);
}
}
Here you did Mistakes
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflater.inflate(R.layout.listview, null);
TextView textView = (TextView) view.findViewById(R.id.tv);
textView.setText(animals[i]);
return view;
}
And
public long getItemId(int i) {
return animals.length;
}
Screenshort
I have seen a lot of similar questions about this issue but I couldn't find any solution to this:
I have three fragments in a TabLayout handled by a ViewPager and I have a ListView in the third Fragment which is not displaying any items after I change the orientation of the screen. I have tried to set a background color to the convertView in the ArrayAdapter to see if it was displayed and indeed it is not being displayed after I change the orientation. But it's weird because in my First Fragment where I use the same ArrayAdapter for another ListView everything's working and I can't understand why it's not on the third Fragment.
One thing is sure: I have checked with logs almost everywhere that the ArrayList.size() is never zero.
Here's the Third Fragment's relevant code:
public class SavedScanFragment extends Fragment{
private ListView lv;
private Database db;
private ArrayList<Scan> scans;
private ScanAdapter adapter;
public static SavedScanFragment newInstance() {
return new SavedScanFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = new Database(getContext());
getScans();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.fragment_saved_scan, container, false);
lv = (ListView) result.findViewById(R.id.saved_scan_list);
return result;
}
#Override
public void onResume() {
super.onResume();
db = new Database(getContext());
getScans();
}
public void getScans() {
AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
scans = db.getScans();
if(scans!=null)
return true;
else {
scans = new ArrayList<>();
return false;
}
}
#Override
protected void onPostExecute(Boolean result) {
if(result)
populateList();
}
};
task.execute();
}
public void populateList() {
if(getContext()!=null) {
if (lv.getAdapter() == null) {
adapter = new ScanAdapter(getContext(), R.layout.scan_list_item, scans);
lv.setAdapter(adapter);
} else {
((ScanAdapter) lv.getAdapter()).update(scans);
}
}
}
And the ArrayAdapter's code:
public class ScanAdapter extends ArrayAdapter<Scan> implements ListAdapter {
private Context context;
private int layoutResourceID;
private ArrayList<Scan> results;
public ScanAdapter(Context context, int layoutResourceID, ArrayList<Scan> results) {
super(context, layoutResourceID, results);
this.context = context;
this.layoutResourceID = layoutResourceID;
this.results = results;
}
public void update(ArrayList<Scan> scans) {
results.clear();
results.addAll(scans);
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView; //view = row
ViewHolder holder = null;
if(view == null) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(layoutResourceID, parent, false);
view.setBackgroundColor(Color.GREEN);
holder = new ViewHolder();
holder.name = (TextView)view.findViewById(R.id.scan_name_and_date_text);
holder.ssid = (TextView)view.findViewById(R.id.scan_SSID_text);
holder.frequency = (TextView)view.findViewById(R.id.scan_frequency_text);
holder.level = (TextView)view.findViewById(R.id.scan_level_text);
view.setTag(holder);
} else
holder = (ViewHolder) view.getTag();
Scan sr = results.get(position);
holder.name.setText(sr.getName()+" ( "+sr.getDate()+" )");
holder.ssid.setText(sr.getSsid() + " ( " + sr.getBssid() + " )");
holder.frequency.setText(sr.getFrequency()+" MHz");
holder.level.setText(Integer.toString(sr.getLevel())+ " dBm");
return view;
}
static class ViewHolder {
TextView name,ssid, frequency, level;
}
}
Thanks in advance!
From this post. You can try to use onActivityCreated instead of onCreate. Try this:
public class SavedScanFragment extends Fragment{
//....to restore the saved state
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Restore the fragment state here
db = new Database(getContext());
getScans();
}
//add this to save instant state
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//save your important variable here to outstate
}
}
I'm trying to create a 2-line list view in my activity but I've come across one error that I don't know how to fix. How can I achieve this the AppCompat way? I want to achieve something like in the screenshot attached. My error is on line 52.
public class WCLineActivity extends ActionBarActivity {
private class Sample {
private CharSequence title;
private CharSequence summary;
private Class<? extends Activity> activityClass;
public Sample(int titleResId, int summaryResId, Class<? extends Activity> activityClass) {
this.activityClass = activityClass;
this.title = getResources().getString(titleResId);
this.summary = getResources().getString(summaryResId);
}
#Override
public String toString() { return title.toString(); }
public String getSummary(){ return summary.toString(); }
}
private static Sample[] mSamples;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wc_line);
// Instantiate the list of samples.
mSamples = new Sample[]{
new Sample(R.string.bank, R.string.zone_1, MainActivity.class),
new Sample(R.string.waterloo, R.string.zone_1, MainActivity.class)
};
setListAdapter(new MyAdapter(this, mSamples));
}
static class MyAdapter extends BaseAdapter {
static class ViewHolder {
TextView title;
TextView summary;
}
LayoutInflater inflater;
Sample[] mSamples;
public MyAdapter(Context contexts, Sample[] samples) {
this.mSamples = samples;
inflater = LayoutInflater.from(contexts);
}
#Override
public int getCount() {
return mSamples.length;
}
#Override
public Object getItem(int position) {
return mSamples[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item_dualline, null);
viewHolder = new ViewHolder();
viewHolder.title = (TextView) convertView.findViewById(R.id.list_item_title);
viewHolder.summary = (TextView) convertView.findViewById(R.id.list_item_subtitle);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.title.setText(mSamples[position].title);
viewHolder.summary.setText(mSamples[position].getSummary());
return convertView;
}
}
}
setListAdapter is a method of ListActivity, and it is not available in Activity. To overcame it, you can declare a ListView in your layout, retrieve the ListView with findViewById and call setAdapter, on that object. E.g.
ListView listView = (ListView) findViewById(R.id.id_list);
listView.setAdapter(new MyAdapter(this, mSamples));
I tried with your code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wc_line);
ListView listView = (ListView) findViewById(R.id.listView);
// Instantiate the list of samples.
mSamples = new Sample[]{
new Sample(R.string.bank, R.string.zone_1, MainActivity.class),
new Sample(R.string.waterloo, R.string.zone_1, MainActivity.class)
};
listView.setAdapter(new MyAdapter(this, mSamples));
}
I have implemented the Universal Image Loader into my app with a gridview layout.
When I press a button I want to add a new imageUrl to the Array of Urls.
I managed to do that, but when I refresh my imageList, I still only see the images that were in the Array on StartUp.
How can I update the gridView with the new Array?
EDIT
MainActivity
public class MainActivity extends Activity {
Button btnView;
private ListView listView;
Socket client;
PrintWriter printwriter;
EditText textField;
Button button;
String messsage;
ObjectInputStream input;
ObjectOutputStream output;
int counter = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.ac_home);
//startRunning();
}
public void onImageGridClick(View view) {
Intent intent = new Intent(this, ViewImages.class);
startActivity(intent);
}
public void onTakeImageClick(View view) throws IOException {
ViewImages.addImg();
}
}
And here is the ViewImage class
public class ViewImages extends Activity {
private ListView listView;
ImageLoader loader;
private static ImageListAdapter adapter;
private static List<String> mItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mItems = new ArrayList<String>();
mItems.add("http://195.178.234.228/images/image8.jpg");
mItems.add("http://195.178.234.228/images/image7.jpg");
adapter = new ImageListAdapter(this, mItems);
//
listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(adapter);
}
public static void addImg(){
mItems.add("http://195.178.234.228/images/image10.jpg");
adapter.notifyDataSetChanged();
}
}
ImageListAdapter
public class ImageListAdapter extends BaseAdapter {
List<String> list;
int size;
private Context context;
private ImageLoader imageLoader;
public ImageListAdapter(Context context,List<String> list) {
this.context = context;
this.list = list;
imageLoader = ImageLoader.getInstance();
imageLoader.clearDiscCache();
imageLoader.clearMemoryCache();
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View v = convertView;
ViewHolder vh = null;
if (v == null) {
v = View.inflate(context, R.layout.list_item, null);
vh = new ViewHolder();
vh.imageView = (ImageView) v.findViewById(R.id.imageView);
v.setTag(vh);
}
else {
vh = (ViewHolder)v.getTag();
}
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheOnDisc()
.build();
imageLoader.displayImage(list.get(position), vh.imageView, options);
return v;
}
private class ViewHolder {
ImageView imageView;
}
}
Use notifyDataSetChanged on gridView Adapter to reflect changes in the gridview. Whenever there is a new imageUrl added to array of URL's refresh the adapter by :
adapter.notifyDataSetChanged();