Array and Adapter cant called on Void Fragment - android

Please help me. My Home Fragment is blank. I cant print JSON array to my Home Fragment. i want the ListView show data from Json array from API, how i can place the array data from Json using fragment. Sory for my english.
I'm using Fragment:
public class HomeFragment extends Fragment implements OnFeedListener{
ListView listView;
FeedAdapter adapter;
ArrayList<Post> posts;
View myView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.home, container, false);
return myView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onFeed(JSONArray array) {
posts = new ArrayList<>();
int lenght = array.length();
for(int i = 0; i < lenght; i++)
{
JSONObject object = array.optJSONObject(i);
Post post = new Post(object.optString("title"), object.optString("excerpt"), object.optString("thumbnail"));
posts.addAll(posts);
}
adapter.addAll(posts);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
FeedTask task = new FeedTask(this);
task.execute("http://indo-coc.com/api/get_recent_posts/");
}
public class FeedTask extends AsyncTask<String, Void, JSONArray>
{
private OnFeedListener listener;
public FeedTask(OnFeedListener listener)
{
this.listener = listener;
}
#Override
protected JSONArray doInBackground(String... params)
{
String url = params[0];
OkHttpClient client = new OkHttpClient();
Request.Builder builder = new Request.Builder();
Request request = builder.url(url).build();
try {
Response response = client.newCall(request).execute();
String json = response.body().string();
try
{
JSONObject object = new JSONObject(json);
JSONArray array = object.optJSONArray("posts");
return array;
}
catch (JSONException e)
{
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONArray array) {
super.onPostExecute(array);
if(null == array)
return;
if(null != listener )
listener.onFeed(array);
}
}
public class FeedAdapter extends ArrayAdapter<Post>
{
private int resource;
public FeedAdapter(Context context, int resource) {
super(context, resource);
this.resource = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Convert View -> Reuse
if (null==convertView)
{
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(resource, null);
}
// Binding Data
Post post = getItem(position);
TextView title = (TextView) convertView.findViewById(R.id.title);
TextView desc = (TextView) convertView.findViewById(R.id.description);
title.setText(post.title);
desc.setText(post.description);
return convertView;
}
}
public class Post
{
public String title;
public String description;
public String thumbnail; //URL
public Post(String title, String desc, String thumbnail)
{
this.title = title;
this.description = desc;
this.thumbnail = thumbnail;
}
}
}

Declare FeedAdapter adapter and ArrayList<Post> posts as global variable in your public class. They must be declared outside public void onActivityCreated(Bundle savedInstanceState)

what's going on here:
in onActivityCreated you declare local variables without assigning a value to them. Because they are local, they are gone as soon as the method terminates. Declare the variables above the method as a class variable to be able to access them later in onFeed
you do not assign a value to the variables listView and adapter. I assume somewhere else, common practice is doing this in onViewCreated, you set a main view for the fragment. If you don't know how to do this, see this question. Then you can load the listView using findViewById assuming the listView is in the layout you inflate in the fragment. Then you have to create a new FeedAdapter and assign it to the listView using listView.setAdapter(adapter)
Good luck!

try this:
class MyFragment extends Fragment{
ListView listView;
FeedAdapter adapter;
ArrayList<Post> posts;
public void onCreate(Bundle b){
super.onCreate(b);
//My bad listview will only be assigned properly in onCreateView once the view is inflated
posts = new ArrayList<>();
adapter=new FeedAdapter(getActivity(),R.id.yourresouceid,posts); // which ever way your adapter is defined
listView.setAdapter(adapter);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void onFeed(JSONArray array) {
int lenght = array.length();
for (int i = 0; i < lenght; i++)
{
JSONObject object = array.optJSONObject(i);
posts.add(post);
}
//adapter.addAll(posts); //you don't need to do this, already done when creating your adapter
adapter.notifyDataSetChanged();
}
}
Explanation: The scope of onActivityCreated is only till its closing bracket. Anything declared inside that will not be visible to any outer functions. See scope resolution in java for more details on how this works.
Also you have to initialize things before using them. just declaring it and trying to use it will give NullPointerExceptions

Related

Volley shows null error when activity loads first time

I have view pager in my android activity and using NodeJs and MongoDb as a back-end service.When my activity starts first time it shows volley error null
and when i stop my app and start it again it loads images in the view pager and works fine.
Why it is not fetching data from the server when activity starts first time.
Here is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
TabLayout tab;
RequestQueue rq;
List<Model> list;
Adapter adapter;
String request_url = "https://example.com";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rq = CustomRequest.getInstance(MainActivity.this).getRequestQueue();
viewPager = findViewById(R.id.viewPager);
tab = findViewById(R.id.tabLayout);
list = new ArrayList<>();
tab.setupWithViewPager(viewPager, true);
final ProgressDialog prg = new ProgressDialog(MainActivity.this);
prg.setMessage("Loading");
prg.show();
StringRequest stringRequest = new StringRequest(Request.Method.POST, request_url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
prg.dismiss();
try {
JSONArray jsonArr = new JSONArray(response);
for (int i = 0; i < jsonArr.length(); i++) {
Model model = new Model();
JSONObject jsonObject = jsonArr.getJSONObject(i);
model.setImage(jsonObject.getString("Image"));
list.add(model);
}
adapter = new Adapter((ArrayList<Model>) list, MainActivity.this);
viewPager.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
prg.dismiss();
Toast.makeText(getApplicationContext(),""+error.getMessage(),Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> params = new HashMap<>();
params.put("place","Ajmer");
return params;
}
};
CustomRequest.getInstance(MainActivity.this).addToRequetQueue(stringRequest);
}
}
Adapter.java
public class Adapter extends PagerAdapter {
ArrayList<Model> list = new ArrayList<>();
Context context;
LayoutInflater layoutInflater;
public Adapter(ArrayList<Model> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object o) {
return view == o;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, final int position) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assert layoutInflater != null;
View view = layoutInflater.inflate(R.layout.custom, null);
Model model = list.get(position);
ImageView imageView = view.findViewById(R.id.imageView);
Glide.with(context).load(model.getImage()).into(imageView);
ViewPager vp = (ViewPager) container;
vp.addView(view, 0);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((LinearLayout)object);
}
}
Please someone let me know why I am getting this issue.
THANKS
Did you initialized RequestQueue. if not please add following code before string request
RequestQueue queue = Volley.newRequestQueue(context);
After that call add queue.add after string request call
queue.add(stringRequest);
If the error still continues...
print response of volley whether its getting null or not.

Passing ArrayList from AsyncTask to PagerAdapter

hope you fine and well,
i have the following main class :
public class MainActivity extends AppCompatActivity {
Activity activity;
ViewPager viewPager;
CustomAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager=(ViewPager)findViewById(R.id.view_pager);
adapter=new CustomAdapter(this);
viewPager.setAdapter(adapter);
ConnectionAsyncTask connectionAsyncTask = new
ConnectionAsyncTask(MainActivity.this);
connectionAsyncTask.execute("http://www.mocky.io/v2/570d3677270000f600dc29b6");
}
public void showUploader()
{
// findViewById(R.id.progressBar1).setVisibility(View.VISIBLE);
}
public void hideUploader()
{
//findViewById(R.id.progressBar1).setVisibility(View.GONE);
}
public void DisplyOnTextView(List< Student > students) {
List <Student> my = students ;
}
}
when i run the app, this main activity will use another class to read json data from link as follows:
public class StudentJasonParser {
public static List<Student> getObjectFromJason(String jason)
{
List<Student> students;
try {
JSONArray jsonArray = new JSONArray(jason);
students = new ArrayList<>();
for(int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject = new JSONObject();
jsonObject= (JSONObject) jsonArray.get(i);
Student student = new Student();
student.setID(jsonObject.getInt("id"));
student.setName(jsonObject.getString("name"));
student.setUrl(jsonObject.getString("url"));
student.setDes(jsonObject.getString("des\n"));
student.setRate(jsonObject.getDouble("rate"));
student.setLon(jsonObject.getDouble("lon"));
student.setLat(jsonObject.getDouble("lat"));
students.add(student);
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return students;
}
}
now this class will return the data to the following class :
public class ConnectionAsyncTask extends AsyncTask<String,String,String> {
Activity activity;
public ConnectionAsyncTask(Activity activity) {
this.activity=activity;
}
#Override
protected void onPreExecute() {
//((MainActivity)activity).DisplyOnTextView();
((MainActivity)activity).showUploader();
}
#Override
protected String doInBackground(String... params) {
String content =HttpManager.getData(params[0]);
return content;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String s) {
((MainActivity)activity).hideUploader();
List<Student> students= StudentJasonParser.getObjectFromJason(s);
if (students != null) {
((MainActivity) activity).DisplyOnTextView(students);
}
}
}
this line : ((MainActivity)activity).DisplyOnTextView(students);
will return the fetched data to the main class in the following function (mentioned in the main class ! )
public void DisplyOnTextView(List< Student > students) {
List <Student> my = students ;
}
now what i want is to pass this list to the following class in order to use it in the imageView and textView in the viewPager instead of the pre-defined data in the class :
public class CustomAdapter extends PagerAdapter {
private int[] images = {R.drawable.sample_0,R.drawable.sample_1};
private Context ctx;
private LayoutInflater LayoutInflater;
public CustomAdapter(Context ctx)
{
this.ctx=ctx;
}
#Override
public int getCount() {
return images.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = LayoutInflater.inflate(R.layout.slide_layout,container,false);
ImageView imageView =(ImageView) view.findViewById(R.id.image_view);
TextView textView = (TextView)view.findViewById(R.id.image_count);
imageView.setImageResource(images[position]);
textView.setText(""+position);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
any idea ?!
thanks, regards.
what i want is to pass this list to the following class in order to use it in the imageView and textView in the viewPager
Then simply pass in the list as a parameter to the adapter and add a member variable for it. The usage of this adapter is at the bottom of this post, because I want to mention some other stuff.
class CustomAdapter extends PagerAdapter {
private Context ctx;
private List<Student> data;
public CustomAdapter(Context ctx, List<Student> students) {
this.ctx = ctx;
this.data = students;
}
If you want to use that data variable in the instantiateItem method, then you can do Student s = this.data.get(position); and use the various methods on the Student object to load the TextView or ImageView.
Please note that you will need an image loading library (Picasso, Glide, Fresco, etc.) to load a URL into an ImageView. While on the topic of libraries, though, you will save yourself much development time by looking into Gson for JSON parsing and Retrofit or Volley for HTTP network calls with JSON data.
As for your usage of the AsyncTask, passing around the Activity variable is bad practice. Try to use an asynchronous callback to the Activity instead.
public interface AsyncResponse<T> {
void onResponse(T response);
}
public class ConnectionAsyncTask extends AsyncTask<String, Void, List<Student>> {
private AsyncResponse<List<Student>> callback;
public ConnectionAsyncTask(AsyncResponse<List<Student>> callback) {
this.callback = callback;
}
#Override
protected List<User> doInBackground(String... params) {
String url = params[0];
final List<Student> students = new ArrayList<Student>();
// TODO: JSON stuff
return students;
}
#Override
protected void onPostExecute(List<Student> result) {
if (this.callback != null) {
this.callback.onResponse(result);
} else {
Log.w("ConnectionAsyncTask", "Ignoring result");
}
}
}
public class SampleViewPagerActivity extends Activity {
private ViewPager pager;
private PagerAdapter adapter;
private ArrayList<Student> students;
private ProgressDialog progress;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 1. Inflate a layout
setContentView(R.layout.viewpager_activity);
// 2. Initialize the views
this.pager = (ViewPager) findViewById(R.id.pager);
this.progress = new ProgressDialog(this);
this.progress.setTitle("Loading");
this.progress.setMessage("Please wait");
// 3. Populate the views with data
this.students = new ArrayList<Student>();
this.adapter = new CustomAdapter(this, students);
this.pager.setAdapter(adapter);
// This code runs later, after 'execute' is called and the response is returned
ConnectionAsyncTask task = new ConnectionAsyncTask(new AsyncResponse<List<Student>>() {
#Override
public void onResponse(List<Student> response) {
students.clear();
students.addAll(response);
adapter.notifyDataSetChanged();
progress.hide();
}
});
// Optionally show some progress while waiting
this.progress.show();
// TODO: Use real URL
task.execute("http://www.somesite.com/data");
}
}

how to send ArrayList(Bitmap) from asyncTask to Fragment and use it in Arrayadapter

I want to send a list of bitmap i retreived from mysql database using asyncTask to the fragment Fragment_ListView.class, in this fragment class i want to set the adapter of the listView with the bitmap token from asyncTask but i don't know how to do that.
Async Task
#Override
protected void onPostExecute(ArrayList<Bitmap> bitmapArrayList) {
super.onPostExecute(bitmapArrayList);
loading.dismiss();
// now after getting images from server , i want to send this bitmapArrayList
// to Fragment_ListView where i set the adapter of the
}
#Override
protected ArrayList<Bitmap> doInBackground(String... params) {
imageList = new ArrayList();
String add1 = "http://192.168.1.11/save/load_image_from_db.php?id=1";
String add2 = "http://192.168.1.11/save/load_image_from_db.php?id=2";
String add3 = "http://192.168.1.11/save/load_image_from_db.php?id=3";
URL url;
Bitmap image = null;
String[] adds = {add1, add2, add3};
for (int i = 0; i < adds.length; i++) {
try {
url = new URL(adds[i]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
image = BitmapFactory.decodeStream(connection.getInputStream());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
imageList.add(image);
image = null;
}
return imageList;
OnCreate of MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listfrg = new Fragment_ListView();
getFragmentManager().beginTransaction().add(R.id.frml, listfrg).commit();
}
Fragment_ListView :
public class Fragment_ListView extends Fragment {
ListView mListView;
static ArrayList<Bitmap> bitmaps;
static MySimpleArrayAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frglist, container, false);
mListView = (ListView) view.findViewById(R.id.listView);
bitmaps = new ArrayList<>();
adapter = new MySimpleArrayAdapter(getActivity(), bitmaps);
mListView.setAdapter(adapter);
return view;
}
Something like this,
Create a new interface file
public interface BitMapArrayCallBack {
abstract void bitmapArray(ArrayList<Bitmap> bitmaps);
}
Then in AsyncTask ... i don't know your class name so i will assume the class ServerRequest
public class ServerRequest {
Context context;
public ServerRequest(Context context) {
this.context = context;
}
public void doAsyncTask(BitMapArrayCallBack bitmapCallback) {
new MyAsyncTask(bitmapCallback).execute();
}
public class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private BitMapArrayCallBack bitmapCallback;
public MyAsyncTask(BitMapArrayCallBack bitmapCallback) {
this.bitmapCallback = bitmapCallback;
}
//call do in background etc..
#Override
protected void onPostExecute(ArrayList<Bitmap> bitmapArrayList) {
super.onPostExecute(bitmapArrayList);
loading.dismiss();
bitmapCallback.bitmapArray(bitmapArrayList);
// This will hold and return your arraylist
}
}
}
Now you must call your asynctask in fragment listview
public class Fragment_ListView extends Fragment {
ListView mListView;
static MySimpleArrayAdapter adapter;
private ServerRequest serverRequest;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frglist, container, false);
mListView = (ListView) view.findViewById(R.id.listView);
serverRequest = new ServerRequest(getActivity);
serverRequest.doAsyncTask(new BitMapArrayCallBack {
#Override
void bitMapArray(ArrayList<Bitmap> bitmaps) {
// in here you have access to the bitmaps array
adapter = new MySimpleArrayAdapter(getActivity(), bitmaps);
mListView.setAdapter(adapter);
}
})
return view;
}

Loading text in recycler view with card view is too slow

I have a problem with the recycler view and card view. I'm using asynctask to get info from API, and for now I'm getting only a name - which means, I display in my card view only a text view. however, when I'm loading the list, it is awfully slow. in the log cat I can see that the app is getting the data pretty fast, but it takes a lot of time to show it in the recycler view.
I'm adding few samples - from the adapter of the recycler view and the fragment that holds the recycler view in. maybe I did something wrong in the adapter.
Thank you for your help!
Adapter:
public class PlacesListAdapter extends RecyclerView.Adapter<PlacesListAdapter.ListViewHolder>{
ArrayList<PlaceItem> items;
Context context;
public PlacesListAdapter(Context context,ArrayList<PlaceItem> placeItems){
this.context = context;
this.items = placeItems;
}
public void swap(ArrayList<PlaceItem> places){
items.clear();
items.addAll(places);
notifyDataSetChanged();
}
#Override
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.card_view, parent, false);
return new ListViewHolder(v);
}
#Override
public void onBindViewHolder(ListViewHolder holder, int position) {
PlaceItem item = items.get(position);
holder.bindData(item);
}
#Override
public int getItemCount() {
return items.size();
}
public class ListViewHolder extends RecyclerView.ViewHolder{
TextView title;
PlaceItem placeItem;
public ListViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.txtTitlePlace);
}
public void bindData(PlaceItem item){
this.placeItem = item;
title.setText(placeItem.getTitle());
}
}
}
Fragment:
public class FragmentListPlaces extends Fragment implements View.OnClickListener {
ArrayList<PlaceItem> placeItems;
PlacesListAdapter adapter;
RecyclerView list;
EditText editName;
public FragmentListPlaces() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_list_places, container, false);
editName = (EditText) v.findViewById(R.id.editPlaceName);
v.findViewById(R.id.btnGetLocations).setOnClickListener(this);
v.findViewById(R.id.btnSearchByText).setOnClickListener(this);
placeItems = new ArrayList<>();
placeItems.add(new PlaceItem("Example"));
adapter = new PlacesListAdapter(getContext(), placeItems);
list = (RecyclerView) v.findViewById(R.id.placesList);
list.setLayoutManager(new LinearLayoutManager(getContext()));
list.setAdapter(adapter);
return v;
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnGetLocations:
GetUserLocation location = new GetUserLocation();
location.getLocation(getActivity());
adapter.swap(placeItems);
break;
case R.id.btnSearchByText:
// this is the method loading data with user input
String getNameFromUser = editName.getText().toString();
searchPlaceByText(getNameFromUser);
adapter.swap(placeItems);
break;
}
}
public void searchPlaceByText(String place){
// instantiate the asynctask here
LocationDetailsByText locationDetailsByText = new LocationDetailsByText(placeItems);
locationDetailsByText.execute("http://api.v3.factual.com/t/places-il?q=" + place + "&KEY=AFvDryDJmPkkgXohbpFdqkRQelT9w0HKtyEqXy3G");
}
Loading of data from the web:
public class LocationDetailsByText extends AsyncTask<String, Void, String> {
ArrayList<PlaceItem> placeItems = new ArrayList<>();
public LocationDetailsByText(ArrayList<PlaceItem> places){
this.placeItems = places;
}
#Override
protected String doInBackground(String... params) {
StringBuilder result = new StringBuilder();
BufferedReader reader;
HttpURLConnection connection = null;
URL url;
String query = (params[0]);
try {
url = new URL(query);
connection = (HttpURLConnection)url.openConnection();
if(connection.getResponseCode() != 200){
return "Error!";
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = "";
while((line = reader.readLine())!= null){
result.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
connection.disconnect();
}
return result.toString();
}
#Override
protected void onPostExecute(String s) {
PlaceItem placeItem;
try {
JSONObject root = new JSONObject(s);
JSONObject response = root.getJSONObject("response");
JSONArray data = response.getJSONArray("data");
for(int i = 0; i < data.length(); i++){
JSONObject getData = data.getJSONObject(i);
String title = getData.getString("name");
placeItem = new PlaceItem(title);
placeItems.add(placeItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Apart from the issue that #M G pointed out that messes up the behavior in general.
you have 2 other major flaws that I can see of which 1) is affecting you mostly.
1) you do all the Json parsing + moving the data to your POJO(PlaceItem[]) onPostExecute. this is wrong!
this can be very heavy on computation
this way you create 2 many intermediate objects lots of GC
I suggest move these to background and use Gson.
2) it seems that you do lots of network calls that could happen quite frequently. This needs better managing of concurrent requests, network connections, threads, streams and data arrays obtained form the network stream. This can cause lots of GC.
I would recommend to use some networking library made for this purpose such as retrofit, volley or jus. These all can handle also parsing network data straight to your POJO in the background and minimizing GC and performance in general.
Few issues with your code
searchPlaceByText(getNameFromUser);
adapter.swap(placeItems);
adapter.swap(placeItems); starts right after you start your AsyncTask but you didn't download anything yet. This is wrong. You should remove adapter.swap(placeItems); from here and do something like this instead:
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnGetLocations:
GetUserLocation location = new GetUserLocation();
location.getLocation(getActivity());
adapter.swap(placeItems);//also here probably
break;
case R.id.btnSearchByText:
// this is the method loading data with user input
String getNameFromUser = editName.getText().toString();
searchPlaceByText(getNameFromUser);
break;
}
}
public void searchPlaceByText(final String place) {
// instantiate the asynctask here
LocationDetailsByText locationDetailsByText = new LocationDetailsByText(placeItems) {
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter.swap(placeItems);
}
};
locationDetailsByText.execute("http://api.v3.factual.com/t/places-il?q=" + place + "&KEY=AFvDryDJmPkkgXohbpFdqkRQelT9w0HKtyEqXy3G");
}
Next thing is that you clear your list
items.clear();
items.addAll(places);
Which is basically also removing everything from your placeItems because erlier in this class you set this.items = placeItems;. So in PlacesListAdapter just do
public void swap(ArrayList<PlaceItem> places){
notifyDataSetChanged();
}
In Your Asynctask, in OnPostExcute, at the end of it notify your adapter about the changes in your data, that's why you cant see your data unless you click on edit text again.

Problems populating a fragment list

I have a SherlockFragmentActivity class that collects values from a server and loads it in to my database. This SherlockFragmentActivity as 3 Fragment called the Book, Video and Audios. Each of them are meant to show values that were downloaded into the db. By challenge now is when I open my UI i dont get to see the values on the fragments not until I start clicking each fragment before the values get populated into the list in the fragment. And I even notice a continuous addition of this values. My fragment class is pasted below.
public class BooksFragment extends SherlockListFragment{
TextView textview = null;
String CategoryID = null;
ArrayList<HashMap<String,String>> listBooks = null;
IDatabaseHelper databaseHelper = null;
Activity activity = null;
Context context = null;
ListAdapter adapter = null;
public BooksFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.books, container, false);
// do your view initialization heres
textview = (TextView)view.findViewById(R.id.textView1);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
listBooks = new ArrayList<HashMap<String,String>>();
}
#Override
public void onStart() {
super.onStart();
Bundle bundle =this.getArguments();
if(bundle != null){
CategoryID = bundle.getString("CategoryID");
}
this.initializeComponents();
this.populateListView();
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
activity = getActivity();
context = activity.getBaseContext();
databaseHelper= new DatabaseHelper(context);
}
//Now we are going to initialize components of the fragment
private void initializeComponents(){
ListView listview = getListView();
listview.setOnItemClickListener(listener);
}
//list item click listener
private OnItemClickListener listener = new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
}
};
//This method would be used to collect content from the database and populate the listview item
private void populateListView(){
MedicalBookModel[] booksmodel = this.databaseHelper.ReturnBooks(CategoryID);
if(booksmodel != null){
for(MedicalBookModel book : booksmodel){
HashMap<String,String> bookMap = new HashMap<String,String>();
bookMap.put(MedicalBookModel.MedicalBookModel_ID, book.getID());
bookMap.put(MedicalBookModel.MedicalBookModel_Name,book.getName());
Log.i("values",book.getName());
listBooks.add(bookMap);
}
}
adapter = new SimpleAdapter(context, listBooks,R.layout.list_book,new String[]{ "ID","Name"}, new int[]{ R.id.bookId, R.id.bookName});
setListAdapter(adapter);
}
}
For that you have several solutions :
1- Using the Application instance singleton which is global
2- Creating your own global class to manage your data
3- Use a service bound to the activity (or not) and call backs (maybe intent and broadcast receivers)
4- Pass your object as parceable in argument when adding the fragment
Note that sometimes you will need to invalidate views to force datas to refresh
EXEMPLE OF PARCEABLE OBJECT
public class ImageObject implements Parcelable {
/**
* ATTRIBUTES
*/
protected String _idPicture;
protected String _idAlbum;
protected String _name;
protected String _fileName;
protected String _imageUrl;
protected String _hierarchy;
public ImageObject(String _idPicture, String _idAlbum, String _name, String _fileName, String _imageUrl, String _hierarchy) {
super();
this._idPicture = _idPicture;
this._idAlbum = _idAlbum;
this._name = _name;
this._fileName = _fileName;
this._imageUrl = _imageUrl;
this._hierarchy = _hierarchy;
}
public ImageObject(Parcel in) {
String[] data = new String[6];
in.readStringArray(data);
this._idPicture = data[0];
this._idAlbum = data[1];
this._name = data[2];
this._fileName = data[3];
this._imageUrl = data[4];
this._hierarchy = data[5];
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ImageObject createFromParcel(Parcel in) {
return new ImageObject(in);
}
public ImageObject[] newArray(int size) {
return new ImageObject[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this._idPicture, this._idAlbum, this._name, this._fileName, this._imageUrl, this._hierarchy });
}
}

Categories

Resources