I am new to Android programming and I'm trying to create a cardview using recycler view using an API but I am getting the error saying "E/RecyclerView: No adapter attached; skipping layout". I tried looking up the solution online but couldn't seem to figure it out.
I tried the solution given by this link :
http://www.chansek.com/RecyclerView-no-adapter-attached-skipping-layout/
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
mExampleList = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
}
private void parseJSON()
{
String url = "http://apidev.travelhouse.world/api/v1/packages";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject hit = jsonArray.getJSONObject(i);
String holiday_name = hit.getString("holiday_name");
String holiday_price = hit.getString("package_price");
String primary_image = hit.getString("primary_image");
mExampleList.add(new ExampleItem(primary_image,holiday_name,holiday_price));
}
mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
})
{
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
headers.put("X-API-KEY", "CODEX#123");
return headers;
}
};
mRequestQueue.add(request);
}
}
I think this is solution which Vlad Kramarenko recommended. I just implemented it in your code and I agree with it.
So the problem is that you need to set Adapter for RecyclerView at the beginning. Once it is set up, you linked your List of ExampleItems to your RecyclerView through ExampleAdapter. Now every time you change your list and you want to updated your RecyclerView, you need to call notifyDataSetChanged() method on your Adapter which is linked to RecyclerView.
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
mExampleList = new ArrayList<>();
mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
}
private void parseJSON()
{
String url = "http://apidev.travelhouse.world/api/v1/packages";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject hit = jsonArray.getJSONObject(i);
String holiday_name = hit.getString("holiday_name");
String holiday_price = hit.getString("package_price");
String primary_image = hit.getString("primary_image");
mExampleList.add(new ExampleItem(primary_image,holiday_name,holiday_price));
}
mRecyclerView.getAdapter().notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
})
{
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
headers.put("X-API-KEY", "CODEX#123");
return headers;
}
};
mRequestQueue.add(request);
}
Maybe this will sound strange for you, but it says that you create your recyclerview but forgot to add the adapter to recyclerView... But don't forget, you do it. So why?
Answer: when the system tries to draw recyclerView it doesn't have an adapter. You attach adapter in parseJSON function after getting a response from the server. Request and respons from server take some time, but int the meantime system finishes drawing views and says: Hey, your recyclerView doesn't have an adapter, please fix it. You can ignore this warning, but if you want to make all things perfect: you can attach empty adapter in onCreate, and after getting a response do
mRecyclerView.getAdapter().notifyDataSetChanged();
EDIT:
this how will look your onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
mExampleList = new ArrayList<>();
mRecyclerView.setAdapter(new ExampleAdapter(mExampleList, some arguments)
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
}
In the onCreate Method, add after creating array list
mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
Remove them from the try clause
Related
My RecycleView is in my Activity and then I want to set it in my other class. But it always say NullObjectReference with my RecycleView. I dont know why because i have initialize it. Is there something wrong? Here is my code
My Activity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
RecyclerView recyclerView;
VolleyGet volleyGet;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initRecycle();
volleyGet = new VolleyGet();
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
Button get = (Button) findViewById(R.id.get);
get.setOnClickListener(this);
}
public void initRecycle(){
recyclerView = findViewById(R.id.recycleview);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.get:
volleyGet.volleyRequest(this);
break;
default:
break;
}
}
My Other Class (RecycleView must be set here)
public class VolleyGet {
RecyclerView recyclerView;
public RecycleAdapter adapter;
public ArrayList<User> listUser;
public void volleyRequest(final Context context) {
MainActivity mainActivity = new MainActivity();
mainActivity.initRecycle();
listUser = new ArrayList<>();
adapter = new RecycleAdapter(context, listUser);
String URL = "http://192.168.180.7:8080/get.php";
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
ArrayList<User> items = new Gson().fromJson(response.toString(), new TypeToken<ArrayList<User>>() {
}.getType());
listUser.clear();
listUser.addAll(items);
}
recyclerView.setAdapter(adapter);
} catch (JSONException e) { e.printStackTrace(); } }},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) { }}) {};
queue.add(stringRequest);
}
Looks like the RecycleView init with calling a method. You can try initialize with other way like using Activity like this.
Activity activity;
and this how to get your activity
public VolleyGet(Activity _activity){
this.activity = _activity;
recyclerView = (RecyclerView) this.activity.findViewById(R.id.recycleview);
}
or you can do this if you want to use Context
public VolleyGet(Context context){
recyclerView = (RecyclerView) ((Activity)context).findViewById(R.id.recycleview);
}
dont forget to add this in your MainActivity for sending your activity
volleyGet = new VolleyGet(this);
so the whole code of your other class must be like this
public class VolleyGet {
RecyclerView recyclerView;
public RecycleAdapter adapter;
public ArrayList<User> listUser;
Activity activity;
public VolleyGet(Activity _activity){
this.activity = _activity;
recyclerView = (RecyclerView) this.activity.findViewById(R.id.recycleview);
}
public void volleyRequest(final Context context) {
listUser = new ArrayList<>();
adapter = new RecycleAdapter(context, listUser);
String URL = "http://192.168.180.7:8080/get.php";
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
ArrayList<User> items = new Gson().fromJson(response.toString(), new TypeToken<ArrayList<User>>() {
}.getType());
listUser.clear();
listUser.addAll(items);
}
recyclerView.setAdapter(adapter);
} catch (JSONException e) { e.printStackTrace(); } }},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) { }}) {};
queue.add(stringRequest);
I parsed JSON data from URL into a list and now I want to create buttons with every item of the list, but I can't figured out how to do this. I'm not sure if the list is the best idea, but I this was the solution I found online.
public class SecondActivity extends AppCompatActivity {
private String TAG = SecondActivity.class.getSimpleName();
private ProgressDialog pDialog;
private ListView lv;
private static String url = "https://ggysqqcz.p51.rt3.io/available-remotes/TV";
ArrayList<HashMap<String, String>> contactList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
contactList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(SecondActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray remotes = jsonObj.getJSONArray("remotes");
// looping through All Contacts
for (int i = 0; i < remotes.length(); i++) {
JSONObject c = remotes.getJSONObject(i);
String id = c.getString("id");
HashMap<String, String> contact = new HashMap<>();
contact.put("id", id);
contactList.add(contact);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
ListAdapter adapter = new SimpleAdapter(
SecondActivity.this, contactList,
R.layout.list_item, new String[]{"id"}, new int[]{button1});
lv.setAdapter(adapter);
}
}
public void onClickButton1(View view) {
startActivity(new Intent(getApplicationContext(), ThirdActivity.class));
}
}
This shows all the buttons, but obviously they all do the same thing when clicked because I have only button1. How can I make all the buttons do different activities?
I would like to suggest creating a custom adapter for your ListView which will have an onClick function for your button and based on the position of that item in your ListView, you can implement different actions in your onClick function. Hence I would like to suggest an adapter like the following.
public class ListAdapter extends ArrayAdapter<Item> {
private int resourceLayout;
private Context mContext;
private ArrayList<Contact> contacts;
public ListAdapter(Context context, int resource, ArrayList<Contact> contacts) {
super(context, resource, items);
this.resourceLayout = resource;
this.mContext = context;
this.contacts = contacts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(mContext);
v = vi.inflate(resourceLayout, null);
}
Item p = getItem(position);
if (p != null) {
Button btn = (TextView) v.findViewById(R.id.button1);
if (btn != null) {
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(position == 1) implementSomethingFor1();
else if (position == 2) implementSomethingFor2();
// ... Define the other implementations
}
});
}
}
return v;
}
}
And then use the adapter like the following.
ListView lv = (ListView) findViewById(R.id.list);
ListAdapter customAdapter = new ListAdapter(this, R.layout.list_item, contactList);
lv.setAdapter(customAdapter);
Please note that this is not an exact implementation. You should modify your custom adapter so that it serves your purpose.
try
lv.setonitemclicklisnter, this will create a method which will allow you to click on each and every item, you can write for example A Toast message inside this method so when you click on an item a Toast message will pop up.
You have several options:
Check the view parameter to determine what to do. You can use getTag() and setTag() to provide custom data on each button.
Create a custom adapter by extending SimpleAdapter. Override createView() and bindView() in order to provide custom behavior for each button, such as adding a different OnClickListener object to each button
Set the OnItemClickListener for the ListView. This provides a parameter for which position in the list view was clicked. You can use that to determine what to do or what data to pass to the new activity. You will likely want to use getItem() from your adapter to get the data for the current row.
I have created a Custom Listview that will display area list from my database but sometimes the data won't display. After staying in the activity for a couple of seconds and restarting the activity again it will display the list. Here is my code can you check this out ? If see what's the problem. Thanks!
AreaListActivity.java
private ListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setupActionBar();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
#Override
protected void onResume() {
super.onResume();
setupList();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle arrow click here
if (item.getItemId() == android.R.id.home) {
finish(); // close this activity and return to preview activity (if there is any)
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Only if you need to restore open/close state when
// the orientation is changed
if (adapter != null) {
adapter.saveStates(outState);
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Only if you need to restore open/close state when
// the orientation is changed
if (adapter != null) {
adapter.restoreStates(savedInstanceState);
}
}
private void setupList() {
ListView listView = (ListView) findViewById(R.id.list_view);
adapter = new ListAdapter(this, createList());
listView.setAdapter(adapter);
}
private List<String> createList() {
final List<String> list = new ArrayList<>();
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
GetAreaListRequest registerRequest = new GetAreaListRequest("True", responseListener);
RequestQueue queue = Volley.newRequestQueue(AreaListActivity.this);
queue.add(registerRequest);
return list;
}
private void setupActionBar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
}
GetAreaListRequest.java
public class GetAreaListRequest extends StringRequest {
private static final String GET_AREA_LIST_URL = "http://192.168.1.7:8080/smsams/get_area_list.php";
private Map<String, String> params;
public GetAreaListRequest(String get_area_status, Response.Listener<String> listener) {
super(Method.POST, GET_AREA_LIST_URL, listener, null);
params = new HashMap<>();
params.put("get_area_status", get_area_status);
}
#Override
public Map<String, String> getParams() {
return params;
}
ListAdapter.java
class ListAdapter extends ArrayAdapter<String> {
private final LayoutInflater mInflater;
private final ViewBinderHelper binderHelper;
private Context context;
ListAdapter(Context context, List<String> objects) {
super(context, R.layout.row_list, objects);
mInflater = LayoutInflater.from(context);
binderHelper = new ViewBinderHelper();
this.context = context;
// uncomment if you want to open only one row at a time
// binderHelper.setOpenOnlyOne(true);
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.row_list, parent, false);
holder = new ViewHolder();
holder.textView = (TextView) convertView.findViewById(R.id.text);
holder.statView = convertView.findViewById(R.id.statistic_layout);
holder.mapView = convertView.findViewById(R.id.map_layout);
holder.infoView = convertView.findViewById(R.id.info_layout);
holder.swipeLayout = (SwipeRevealLayout) convertView.findViewById(R.id.swipe_layout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final String item = getItem(position);
if (item != null) {
binderHelper.bind(holder.swipeLayout, item);
holder.textView.setText(item);
holder.statView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, StatisticActivity.class);
context.startActivity(i);
}
});
holder.mapView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, MapsActivity.class);
i.putExtra("soilArea", holder.mapView.toString());
context.startActivity(i);
}
});
holder.infoView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, InfoViewActivity.class);
context.startActivity(i);
}
});
}
return convertView;
}
/**
* Only if you need to restore open/close state when the orientation is changed.
* Call this method in {#link android.app.Activity#onSaveInstanceState(Bundle)}
*/
void saveStates(Bundle outState) {
binderHelper.saveStates(outState);
}
/**
* Only if you need to restore open/close state when the orientation is changed.
* Call this method in {#link android.app.Activity#onRestoreInstanceState(Bundle)}
*/
void restoreStates(Bundle inState) {
binderHelper.restoreStates(inState);
}
private class ViewHolder {
TextView textView;
View statView;
View mapView;
View infoView;
SwipeRevealLayout swipeLayout;
}
Try this:
private List<String> list = new ArrayList<>();
private void setupList() {
ListView listView = (ListView) findViewById(R.id.list_view);
adapter = new ListAdapter(this, list);
listView.setAdapter(adapter);
}
private void createList() {
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
};
GetAreaListRequest registerRequest = new GetAreaListRequest("True", responseListener);
RequestQueue queue = Volley.newRequestQueue(AreaListActivity.this);
queue.add(registerRequest);
}
The network requests usually happens in an asynchronous way. So there is no specific time that the onResponse() gets called. So in your createList() method you initialised an empty arraylist and before the request produces the response(asynchronously calls onResponse) the list which contains no value is returned.
You can change your code something like this:
In createList():
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
String areaName = obj.getString("area_name");
list.add(areaName);
adapter = new ListAdapter(this, list);
listView.setAdapter(adapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
So here the adapter is set only after the data is pulled from the network.
I am trying to load some items from JSON, I am able to get and parse the JSON and load it up in listview when using one activity. However, I want to use a LoadJSON.class to load the JSON, and then the activity can call the json passed and show it in the listview in that activity.
Here is what I have tried:
SongsManager.class
public class SongsManager {
private String TAG = SongsManager.class.getSimpleName();
private static final String API_URL = "http://xxxxxxxxxxxxx.com/jame/mp3/songlist.json";
private List<SolTracks> solTracksList;
private ProgressDialog pDialog;
private final Activity activity;
public SongsManager(Activity activity) {
this.activity = activity;
solTracksList = new ArrayList<>();
pDialog = new ProgressDialog(activity);
fetchSongs();
}
private void fetchSongs() {
pDialog.setMessage("Fetching Playlist...");
pDialog.show();
// Volley's json array request object
JsonArrayRequest req = new JsonArrayRequest(API_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, "Responser = " + response.toString());
pDialog.hide();
if (response.length() > 0) {
// looping through json and adding to movies list
for (int i = 0; i < response.length(); i++) {
try {
JSONObject movieObj = response.getJSONObject(i);
String songTitle = movieObj.getString("title");
String songId = movieObj.getString("id");
String streamUrl = movieObj.getString("stream_url");
SolTracks m = new SolTracks(songTitle, songId, streamUrl);
solTracksList.add(m);
Collections.sort(solTracksList, new TrackComparator());
} catch (JSONException e) {
Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Server Error: " + error.getMessage());
pDialog.hide();
Snackbar snackbar = Snackbar
.make(activity.findViewById(android.R.id.content), "PLEASE CHECK YOUR INTERNET", Snackbar.LENGTH_LONG)
.setAction("DISMISS", new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
// Changing snackbar background
snackbar.getView().setBackgroundColor(ContextCompat.getColor(activity, R.color.colorPrimary));
// Changing message text color
snackbar.setActionTextColor(Color.YELLOW);
// Changing action button text color
View sbView = snackbar.getView();
TextView textView = (TextView) sbView.findViewById(android.support.design.R.id.snackbar_text);
textView.setTextColor(Color.WHITE);
snackbar.show();
}
});
req.setRetryPolicy(new DefaultRetryPolicy(0, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req);
}
public List<SolTracks> getList() {
return solTracksList;
}
Activity class
public class TheMain1 extends AppCompatActivity {
private SwipeRefreshLayout swipeRefreshLayout;
private String TAG = TheMain1.class.getSimpleName();
private static final String API_URL = "http://xxxxxxxxxxx.com/jame/mp3/songlist.json";
private ListView listView;
private SolTracksAdapter adapter;
private ProgressDialog pDialog;
private List<SolTracks> songslist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_the_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
listView = (ListView) findViewById(R.id.track_list_view);
songslist = new ArrayList<>();
SongsManager songsManager = new SongsManager(this);
songslist = songsManager.getList();
adapter = new SolTracksAdapter(this, songslist);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SolTracks track = songslist.get(position);
final String stream_url = track.stream_url;
final String id_url = track.id;
Intent intent = new Intent(TheMain1.this, PlayerActivity.class);
intent.putExtra("songPosition", position);
intent.putExtra("streamUrl", stream_url);
startActivity(intent);
}
}
);
}
As it is right now, I know the JSON is loaded from SongsManager, but its just not displaying in the listview of the Activity class. Can anyone help, and show what I'm doing wrong? Thanks
I was able to fix this by implementing Parcelable to send the list to the receiving activity.
public class SolTracks implements Parcelable {
public String title;
public String id;
public String stream_url;
}
Sending the list from the Activity A:
Intent intent = new Intent(TheMain.this, PlayerActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("mylist", solTracksList);
intent.putExtras(bundle);
intent.putExtra("songPosition", position);
startActivity(intent);
and then receiving in Activity B:
Bundle extras = getIntent().getExtras();
if (extras != null) {
songPosition = extras.getInt("songPosition");
trackList = extras.getParcelableArrayList("mylist");
}
UPDATED POST:
FriendsFragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
parentView = inflater.inflate(R.layout.fragment_friends, container, false);
recyclerView = (RecyclerView) parentView.findViewById(R.id.list_main);
mArrayList = new ArrayList<>();
bindViews();
setHasOptionsMenu(true);
return parentView;
}
private void bindViews() {
parentActivity = (MainActivity) getActivity();
adapter = new PostThreadAdapter(parentView.getContext(), postsArrayList);
recyclerView.setAdapter(adapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(parentActivity);
recyclerView.setLayoutManager(layoutManager);
getItemsFromDatabase();
}
private getItemsFromDatabase()
{
StringRequest stringRequest = new StringRequest(StringRequest.Method.PUT, "SERVERURL", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
Gson gson = new Gson();
final FeedResponse feedResponse = gson.fromJson(response, FeedResponse.class);
mArrayList.clear();
mArrayList.addAll(feedResponse.getArrayList());
adapter.notifyDataSetChanged();
}
} catch (Exception e) {
Log.e("C", "CATH " + e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
};
volley.addRequest(stringRequest, "FriendsFragment");
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Collections.sort(mArrayList, new Comparator<Objectx>() {
#Override
public int compare(Objectx d, Objectx t1) {
return t1.getPostType() - d.getPostType();
}
});
adapter.notifydatasetchanged(); // this only work the first time
}
PROBLEM:
I have 1 Activity (MainActivity)
My activity have framelayout and this can contain 2 fragments.
HomeFragment OR UserFragment
My HomeFragment have TabLayout and viewpager that contain 2 fragments:
Tab1: FriendsFragment
Tab2: NotifiFragment
In my friendsfragment I have recyclerview with custom adapter and viewholder.
This works fine the first time, but when I change of fragment (from HomeFragment to UserFragment) and back again to Homefragment the adapter.notifyDataSetChanged(); don't work anymore. I already tried this:
#Override
public void onResume() {
super.onResume();
array.clear();
getInfoFromDatabase(); // this include .addAll array
adapter.notifyDataSetChanged();
Log.d(TAG, "List Frag Resumed");
}
Also:
#Override
public void onResume() {
super.onResume();
adapter = new CustomAdapter(mView.getContext(), array);
recyclerview.setAdapter(adapter);
getInfoFromDatabase(); // this include .addAll array
adapter.notifyDataSetChanged();
Log.d(TAG, "List Frag Resumed");
}
But none works. I'm also using collections sort to order my items and I notice that the items of the array get changed but can't see in the app because notifydatasetchanged does nothing.