I am using Volley to parse Json and populate my Recyclerview in a Fragment. I have found similar threads where solutions included placing adapter in the onResponse method or placing setAdapter before setLayoutManager which have not worked for me. I have tried logging the Json which worked so I am certain the issue is related to the adapter.
I have included the code in my fragment as well as the adapter class.
I have tried different emulators, setting the adapter in different methods and notifying adapter that dataset changed.
private RequestQueue mQueue;
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mlayoutManager = new LinearLayoutManager(getContext());
final RecyclerView.Adapter adapter = new WatchListAdapter(names, names, names, names, names);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(mlayoutManager);
mQueue = Volley.newRequestQueue(getContext());
String url = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=gbp";
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i = 0; i<response.length();i++){
JSONObject obj = null;
try {
obj = response.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
String name = null;
try {
name = obj.getString("id");
names.add(name);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Volley in Tab4", "not working");
}
});
mQueue.add(request);
This is the adapter used.
public class WatchList_CustomRow extends ArrayAdapter {
ArrayList<String> ranks = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
ArrayList<String> prices = new ArrayList<>();
ArrayList<String> caps= new ArrayList<>();
ArrayList<String> changes = new ArrayList<>();
public WatchList_CustomRow(#NonNull Context context,ArrayList<String> rank1, ArrayList<String> names1, ArrayList<String> prices1, ArrayList<String> caps1, ArrayList<String> changes1) {
super(context, R.layout.activity_watch_list__custom_row,rank1);
names = names1;
prices = prices1;
caps=caps1;
changes=changes1;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View customView = inflater.inflate(R.layout.activity_watch_list__custom_row, parent, false);
String singleRank = getItem(position);
String singleName = names.get(position);
String singlePrice = prices.get(position);
String singleCap= caps.get(position);
String singleChange = changes.get(position);
TextView rankTextView = customView.findViewById(R.id.rankTextView);
TextView nameTextView = customView.findViewById(R.id.WatchedCoinName);
TextView priceTextView = customView.findViewById(R.id.WatchedCoinPrice);
TextView capTextView = customView.findViewById(R.id.WatchedcoinMarket);
TextView changeTextView = customView.findViewById(R.id.WatchCoin24Change);
rankTextView.setText(singleRank);
//bodyTextView.setText(singleBody);
nameTextView.setText(singleName);
priceTextView.setText(singlePrice);
capTextView.setText(singleCap);
changeTextView.setText(singleChange);
return customView; }
}
Use RecyclerView.Adapter and there respective methods onCreateViewHolder and onBindViewHolder to bind view and data
you are not even passing data to Adapter after getting response and you are calling notifyDatasetChanged. and for better JSON parsing use GSON and map your object on Model/Pojo class and get arrayList from of them and pass it to adapter.
kindly post JSON Response as well..then would be able to reply with better solution for you.
Related
i want create a fragment and have inside a recycler view for show products ...
but when i render it is show this error : RecyclerView: No adapter attached; skipping layout
below i copy my codes;
this code is for adapter class :
private ArrayList<Products> ProductsList;
private Context context;
public Adapter(ArrayList<Products> productsList, Context context) {
ProductsList = productsList;
this.context = context;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.row_layout, parent, false);
return new MyHolder(v);
}
#Override
public void onBindViewHolder(MyHolder holder, final int position) {
Products products = ProductsList.get(position);
holder.txtName.setText(products.getName());
holder.txtPrice.setText("$ " + products.getPrice());
Picasso.get().load(Config.ipValue + "/images/" + products.getPhoto()).into(holder.imgV);
holder.imgV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(AnimationUtils.loadAnimation(context, android
.R.anim.slide_in_left));
}
});
}
#Override
public int getItemCount() {
return ProductsList.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView txtName;
TextView txtPrice;
ImageView imgV;
public MyHolder(View itemView) {
super(itemView);
txtName = itemView.findViewById(R.id.rowTxtProductName);
txtPrice = itemView.findViewById(R.id.rowTxtPrice);
imgV = itemView.findViewById(R.id.rowImgProduct);
}
}
and this one for web api class :
public class WebApiHandler {
Context context;
String apiLink = "";
ArrayList<Products> products = new ArrayList<>();
public WebApiHandler(Context context) {
this.context = context;
}
void apiConnect(String type) {
switch (type) {
case "getproducts": {
apiLink = Config.getProductsWebApi;
break;
}
}
ProgressDialog dialog = ProgressDialog.show(context, "Connecting...",
"please wait", false, false);
StringRequest request = new StringRequest(Request.Method.POST,
apiLink, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
dialog.dismiss();
showJson(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
dialog.dismiss();
}
});
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(request);
}
private void showJson(String response) {
products.clear();
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String id = object.getString("id");
String name = object.getString("name");
String description = object.getString("description");
String price = object.getString("price");
String photo = object.getString("photo");
Products p = new Products(id, name, description, price, photo);
products.add(p);
}
} catch (JSONException e) {
e.printStackTrace();
}
VerticalFragment.productsArrayList = products;
IData iData = (IData) context;
iData.sendData();
}}
and my fragment code :
public class VerticalFragment extends Fragment implements IData {
RecyclerView rcVertical;
WebApiHandler webApiHandler;
static ArrayList<Products> productsArrayList = new ArrayList<>();
public VerticalFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vertical, container, false);
rcVertical = view.findViewById(R.id.rcVertical);
webApiHandler = new WebApiHandler(getContext());
webApiHandler.apiConnect("getproducts");
rcVertical.addOnItemTouchListener(new RecyclerTouchListener(getContext(), rcVertical,
new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, int position) {
ProductActivity.products = productsArrayList.get(position);
startActivity(new Intent(getContext(), ProductActivity.class));
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
#Override
public void sendData() {
Adapter adapter = new Adapter(productsArrayList, getContext());
rcVertical.setLayoutManager(new LinearLayoutManager((getContext())));
rcVertical.setItemAnimator(new DefaultItemAnimator());
rcVertical.setAdapter(adapter);
}}
i should say i create a interface and have one method i say it sendData
This is a common error when there is no adapter attached to recyclerview upon showing recyclerview. It will not cause any harm to your app, but you could avoid it by setting empty adapter without data, and later when you get your data, provide it to your adapter and notify it
Edit - Example added
Create setter for your list in adapter. After that, in your fragment make adapter global and in onCreateView make instance of your adapter and attach it to recyclerview
adapter = new Adapter(new ArrayList<>(), getContext());
rcVertical.setAdapter(adapter);
...Initialize recyclerview...
And then in your sendData interface put your loaded values in it
adapter.setData(productsArrayList);
adapter.notifyDataSetChanged();
I'm trying to display data from JSON in listView, but whenever I'll try to add some value from json, my list shows me nothing.
Activity
public static final String LOG = hourlyWeather.class.getSimpleName();
double test;
RequestQueue mQuene;
ArrayList<Weather> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hourly_weather);
mQuene = Volley.newRequestQueue(this);
list = new ArrayList<Weather>();
test();
hourlyWeatherAdapter adapter = new hourlyWeatherAdapter(this, list);
ListView listView = (ListView) findViewById(R.id.weatherListView);
listView.setAdapter(adapter);
}
public void test() {
String url = "https://api.openweathermap.org/data/2.5/weather?lat=50.7578594&lon=16.2127653&units=metric&appid=ID";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
response -> {
try {
JSONObject object = response.getJSONObject("main");
for (int i = 0; i<object.length(); i++){
test = object.getDouble("temp");
}
Log.i(LOG,String.valueOf(test));
list.add(new Weather(test));
} catch (JSONException e) {
e.printStackTrace();
}
}, Throwable::printStackTrace);
mQuene.add(request);
}
}
Adapter
public class hourlyWeatherAdapter extends ArrayAdapter<Weather> {
public hourlyWeatherAdapter(#NonNull Context context, ArrayList<Weather> list) {
super(context, 0, list);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.weather_list_item, parent, false);
}
Weather model = getItem(position);
TextView temperature = (TextView) view.findViewById(R.id.hourly_time);
temperature.append(String.valueOf(model.getTemp()));
return view;
}
}
public class Weather {
private double temp;
public Weather(double temp) {
this.temp = temp;
}
public double getTemp() {
return temp;
}
}
When I'll using the Log.i, I can clearly see value from json in my logcat. Where can be issue? I've tried to add some dummy data, and it works out just fine.
You must declare hourlyWeatherAdapter adapter = new hourlyWeatherAdapter(this, list); outside your onCreate() method, and after change your array, you must call notifyDataSetChanged();. Also, you must initialize your list and adapter before call test().
public static final String LOG = hourlyWeather.class.getSimpleName();
double test;
RequestQueue mQuene;
ArrayList<Weather> list;
hourlyWeatherAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hourly_weather);
mQuene = Volley.newRequestQueue(this);
list = new ArrayList<Weather>();
adapter = new hourlyWeatherAdapter(this, list);
ListView listView = (ListView) findViewById(R.id.weatherListView);
listView.setAdapter(adapter);
test();
}
public void test() {
String url = "https://api.openweathermap.org/data/2.5/weather?lat=50.7578594&lon=16.2127653&units=metric&appid=ID";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
response -> {
try {
JSONObject object = response.getJSONObject("main");
for (int i = 0; i<object.length(); i++){
test = object.getDouble("temp");
}
Log.i(LOG,String.valueOf(test));
list.add(new Weather(test));
// Update list
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}, Throwable::printStackTrace);
mQuene.add(request);
}
}
I have been reading the different answers here on stackoverflow and tried to implement their solutions but I am still getting the error:
RecyclerView: No adapter attached; skipping layout
I have spent days on trying to troubleshoot but no luck any help will be appreciated.
public class GaneshMainActivity extends AppCompatActivity {
private static final String URL_DATA = "https://mantraapp.000webhostapp.com/tag/ganesh-mantra?json=1";
private RecyclerView recyclerView;
private GaneshMyAdapter adapter;
private List < GaneshListitem > ganeshListitem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ganesh_mantra);
recyclerView = (RecyclerView) findViewById(R.id.ganesh_recyclerview);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
ganeshListitem = new ArrayList < > ();
load_data_from_server();
}
private void load_data_from_server() {
StringRequest stringRequest = new StringRequest(Request.Method.GET,
URL_DATA,
new Response.Listener < String > () {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("Ganesha Mantra");
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
GaneshListitem data = new GaneshListitem(
object.getString("title"),
object.getString("content"),
object.getString("thumbnail")
);
ganeshListitem.add(data);
}
} catch (JSONException e) {
System.out.println("No content");
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getApplicationContext(), volleyError.getMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
}
I am not sure what I am doing wrong below is GaneshMyadpater.java file
public class GaneshMyAdapter extends RecyclerView.Adapter < GaneshMyAdapter.ViewHolder > {
private List < GaneshListitem > GaneshlistItems;
private Context context;
public GaneshMyAdapter(Context context, List < GaneshListitem > my_data) {
this.context = context;
this.GaneshlistItems = my_data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listitem, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.title.setText(GaneshlistItems.get(position).getHead());
holder.content.setText(GaneshlistItems.get(position).getDesc());
}
#Override
public int getItemCount() {
return GaneshlistItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView content;
public ImageView thumbnail;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.textviewHead);
content = (TextView) itemView.findViewById(R.id.textviewDesc);
thumbnail = (ImageView) itemView.findViewById(R.id.thumbnail);
}
}
}
Add this line in your onCreate
adapter = new GaneshAdapter(this , ganeshListitem);
recyclerView.setAdapter(adapter);
and call notifyDataSetChanged() when items are added in your list
adapter.notifyDataSetChanged();
this will update the recycleview with new data
ganeshListitem = new ArrayList < > ();
adapter = new GaneshAdapter(this , ganeshListitem);
recyclerView.setAdapter(adapter);
load_data_from_server();
make above changes at onCreate()
adapter.addData(ganeshListitem)
Add above line after ganeshListitem.add(data);
public void addData(List<GaneshListitem> list){
GaneshlistItems.addAll(list);
notifyDataSetChanged()
}
Add this above method to your adapter class
You need to implement like this
you have to take arrayList type hashmap and initialise them ArrayList<HashMap<String,String>> allValues=new ArrayList<>();
then you've to put your response values in your hashmap like this
add this in your oncreate
context = getActivity();
RecyclerView.LayoutManager recyclerViewLayoutManager = new LinearLayoutManager(context);
rv_lunch_break.setLayoutManager(recyclerViewLayoutManager);
private void load_data_from_server() {
StringRequest stringRequest = new StringRequest(Request.Method.GET,
URL_DATA,
new Response.Listener < String > () {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("Ganesha Mantra");
for (int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
HashMap<String,String> hashMap=new HashMap<>();
hashMap.put("title",object.getString("title"));
hashMap.put("content",object.getString("content"));
hashMap.put("thumbnail",object.getString("thumbnail"));
allValues.add(hashMap);
adapter=new yourAdapterName(context,allValues);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
System.out.println("No content");
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getApplicationContext(),
volleyError.getMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
In your adapter class you have to take again arrayList type hashmap and hashmap and also initialise them also like this
HashMap<String,String> hashMAp=new HashMap<>();
private ArrayList<HashMap<String,String>> allList;
In your onBindViewHolder you need to extract value like this
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
hashMAp=allList.get(position);
holder.your_TextView_Refrence.setText(hashmap.get("title"));
holder.your_TextView_Refrence.setText(hashmap.get("content"));
}
Happy to help you
Add this code below “
recyclerView.setLayoutManager(new LinearLayoutManager(this));
” :
recycleView. setAdapter(adapter);
And add this code below “
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("Ganesha Mantra");
for (int i = 0; 1 < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
GaneshListitem data = new GaneshListitem(
object.getString("title"),
object.getString("content"),
object.getString("thumbnail")
);
ganeshListitem.add(data);
}
”:
adapter. notifyDataSetChanged();
Im facing issues with RecyclerViewAdapter
Following is my error :
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)'
on line :
recyclerView.setLayoutManager(mLayoutManager);
I set adapter recyclerview when fragment is create and when user click an item in recyclerview , it calls api to update this recyclerview but problem is when user click item above exception occurs
How to fix it
Following is my code :
recyclerView = (RecyclerView) lay_custom_center_post_topic.findViewById(R.id.lv_poll_feed);
AdapDetailTopicPoll adapDetailTopicPoll = new AdapDetailTopicPoll(timelineFeedListModels.get(i).getPost().getPoll());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapDetailTopicPoll);
adapDetailTopicPoll.notifyDataSetChanged();
new_position = i;
public void sendVodePoll(final int position, String poll_id,final int new_position, final List<ProfileFeedListModelTwo.PostBean.PollBean> poll) {
RequestParams params = new RequestParams();
String URL = "xxxx/xx";
params.put("poll_id", poll_id);
AsyncHttpClient client = new AsyncHttpClient();
client.post(URL, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
ArrayList<ProfileFeedListModelTwo.PostBean.PollBean> pollBeanArrayList = new ArrayList<ProfileFeedListModelTwo.PostBean.PollBean>();
StringBuilder result = new StringBuilder();
String vote = null;
String poll_id=null;
String status_vote=null;
Gson gson = new Gson();
try {
List<TopicVoteModel> topicVoteModels = new ArrayList<>();
for (int i=0 ; i<response.length() ; i++){
JSONObject jsonObject = response.getJSONObject(i);
vote = jsonObject.getString("vote");
topicVoteModels.add(gson.fromJson(String.valueOf(jsonObject), TopicVoteModel.class));
}
boolean new_status_vote = Boolean.parseBoolean(status_vote);
poll.get(position).setVote(Integer.parseInt(vote));
poll.get(position).setStatus_vote(new_status_vote);
for (ProfileFeedListModelTwo.PostBean.PollBean pollBean : poll){
pollBeanArrayList.add(pollBean);
}
adapDetailTopicPoll = new AdapDetailTopicPoll(pollBeanArrayList, context);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager); //inline this error
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapDetailTopicPoll);
adapDetailTopicPoll.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter
public class AdapDetailTopicPoll extends RecyclerView.Adapter<AdapDetailTopicPoll.MyViewHolder> {
SearchDetailFragment searchDetailFragment = new SearchDetailFragment();
Context context;
private List<ProfileFeedListModelTwo.PostBean.PollBean> poll = new ArrayList<ProfileFeedListModelTwo.PostBean.PollBean>();
public AdapDetailTopicPoll( List<ProfileFeedListModelTwo.PostBean.PollBean> poll ,Context context){
this.poll = poll;
this.context=context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_profile_feed_topic_poll,parent,false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.tx_poll.setText(""+poll.get(position).getName());
if (poll.get(position).isStatus_vote()==false){
holder.img_vote.setImageResource(R.drawable.vote_t_1);
holder.tx_count_vote.setText(""+poll.get(position).getVote());
}else {
holder.img_vote.setImageResource(R.drawable.vote_t_2);
holder.tx_count_vote.setText(""+poll.get(position).getVote());
}
}
#Override
public int getItemCount() {
return poll.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView tx_poll,tx_count_vote;
public ImageView img_vote;
public MyViewHolder(View view) {
super(view);
tx_poll = (TextView) view.findViewById(R.id.tx_poll);
tx_count_vote = (TextView) view.findViewById(R.id.tx_count_vote);
img_vote = (ImageView) view.findViewById(R.id.img_vote);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ProfileFragment.poll_id = String.valueOf(poll.get(getAdapterPosition()).getId());
searchDetailFragment.sendVodePoll(getAdapterPosition(),ProfileFragment.poll_id,SearchDetailFragment.new_position,poll);
}
});
}
}
}
Write these lines directly in onCreate() method of the activity
adapDetailTopicPoll = new AdapDetailTopicPoll(pollBeanArrayList, context);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapDetailTopicPoll);
and initialize the adapter and arraylist as the global variable.
In RecyclerView there are 2 ways that are commonly used - In the form of a List or in the form of a Grid. So for list formation you'll provide a layout manager like this -
LinearLayoutManager layoutManagerFuture = new LinearLayoutManager(context);
layoutManagerFuture.setOrientation(LinearLayoutManager.VERTICAL);
and for Grid formation
GridLayoutManager layoutManager = new GridLayoutManager(context, totalItemsInOneRow);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
My situation is like this:
My main activity has 3 fragments. The first fragment requests data from the server and tries to render it. I use an AsyncTask inner class to get the data and render in onPostExecute. I render using a SimpleCursorAdapter with a ListView. Rendering works fine. After this is done, I try to manipulate the UI (set value of a TextView) but it is not working. getViewById does not return null or any errors but I still cannot change the value for some reason. Any suggestions are highly appreciated. Here is the Fragment Class that I use:
public class FeedFragment extends Fragment {
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_feed, container, false);
Activity activity = getActivity();
try {
new getFeedData(activity,rootView).execute();
}
finally{
return rootView;
}
}
private class getFeedData extends AsyncTask<Void, Void, String> {
private Context activity;
private View rootView;
public getFeedData(Context context, View main){
this.activity=context;
this.rootView=main;
}
#Override
protected String doInBackground(Void... params) {
try {
HttpRequest request = HttpRequest.get("http://upinion.us/test/feed_sample/");
String response = "";
if (request.ok()) {
response = request.body();
}
return response;
} catch (HttpRequestException exception) {
return null;
}
}
#Override
protected void onPostExecute(String response) {
String[] columns = new String[] {"_id","title","description"};
int[] viewIds = new int[] {R.id.postId,R.id.title,R.id.description};
JSONArray finalResponse;
try {
finalResponse = new JSONArray(response);
} catch (JSONException e) {
e.printStackTrace();
finalResponse = null;
}
MatrixCursor mc = new MatrixCursor(new String[] {"_id","title","description"}); // properties from the JSONObjects
for (int i = 0; i < finalResponse.length(); i++) {
JSONObject jsonObject;
try {
jsonObject = finalResponse.getJSONObject(i);
mc.addRow(new Object[] {jsonObject.get("_id"),jsonObject.get("title"),jsonObject.get("description")});
} catch (JSONException e) {
jsonObject=null;
}
}
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(getActivity(), R.layout.post, mc, columns, viewIds,0);
ListView list = (ListView) this.rootView.findViewById(R.id.feed_feed);
list.setAdapter(mAdapter);
View v;
for (int i = 0; i < list.getCount(); i++) {
v = list.getAdapter().getView(i, null, null);
TextView text = (TextView) v.findViewById(R.id.title);
text.setText("HELLO MOTO");
}
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// selected item
Integer convId = parent.getId();
}
});
}
}
}
As you can see, I pass the activity and the inflated root view to the asynctask, but still no luck. I have spent nearly two days trying to find a solution with no success.
for (int i = 0; i < list.getCount(); i++) {
v = list.getAdapter().getView(i, null, null);
TextView text = (TextView) v.findViewById(R.id.title);
text.setText("HELLO MOTO");
}
this is your problem:
you are NOT supposed to call getView yourself
to update your listview, you need to call adapter.notifyDataSetChanged
and the system will call the updates for you
so remove this piece of code entirely and just replace it with adapter.notifyDataSetChanged