what is the use of this handler while writing android code? - java

Here in the below code a songsManager object is created and then why is this.songsList used to store the song files and why not only songsList is used. Main question is what is the use of this and what exactly is it and when it is used?
My main doubt is that here since no other songsList is declared so there is no chance of songsList clashing so why to specifically refer to it as the songsList declared in the present class. Mainly I use it when there are arguments passed to a function whose names are same as that of objects or variables declared within the class so to avoid confusion and to tell the compiler that I want to use the object declared in that class and not the one passed as an argument I used this.. Please correct me if I am wrong and add to my knowledge about this.
The code lines of interest are followed by //
please see to it
public class CustomizedListView extends Activity{
private int currentIndex;
private String[] menuItems = {"Play","Share Music Via","Details"};
private LinkedList<File> songsList = new LinkedList<File>();//
private ArrayList<HashMap<String, String>> songsListdata = new ArrayList<HashMap<String, String>>();
private MediaMetadataRetriever mmr = new MediaMetadataRetriever();
private Utilities utils=new Utilities();
ListView list=null;
ModifiedAdapter adapter=null;
SongsManager plm=null;//
Button search;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playlist);
plm = new SongsManager();//
File extStore = Environment.getExternalStorageDirectory();
// get all songs from sdcard
this.songsList = plm.getFilesInFolder(extStore);//
for (int i = 0; i < songsList.size(); i++) {
// creating new HashMap
HashMap<String, String> song = new HashMap<String, String>();
mmr.setDataSource(songsList.get(i).getAbsolutePath().toString());
//getting artist
String artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST);
if(artist==null)
artist=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
//getting Duration
String len = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long Len=0;
try
{
Len=Integer.parseInt(len);
}
catch(Exception e)
{
Log.i(null, ":conversion error");
}
len=utils.milliSecondsToTimer(Len);
Log.i(null, "length"+len);
song.put("songTitle", (songsList.get(i)).getName().substring(0, ((songsList.get(i)).getName().length() - 4)));
song.put("songArtist", artist);
song.put("duration", len);
song.put("songPath",songsList.get(i).getAbsolutePath().toString());
// adding HashList to ArrayList
songsListdata.add(song);
}
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new ModifiedAdapter(this, songsListdata);
list.setAdapter(adapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
final int position, long id) {
final String songPath =songsList.get(position).getAbsolutePath().toString();
AlertDialog.Builder builder = new AlertDialog.Builder(CustomizedListView.this);
builder.setTitle((songsList.get(position)).getName().substring(0, ((songsList.get(position)).getName().length() - 4)));
builder.setItems(menuItems, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int item)
{
if(item==0)
{
Intent in = new Intent(getApplicationContext(),MainActivity.class);
// Sending songIndex to PlayerActivity
in.putExtra("songIndex", position);
setResult(100, in);
// Closing PlayListView
finish();
}
else if(item==2)
{
Intent details = new Intent(getApplicationContext(),Details.class);
details.putExtra("songPath", songPath);
startActivity(details);
}
else if(item==1)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("audio/*");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(songPath)));
startActivity(intent);
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
//Search for a song implementations
search=(Button)findViewById(R.id.searchForSong);
search.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent launchBrowser=new Intent(getApplicationContext(), Browser.class);
startActivity(launchBrowser);
}
});
}
}

Actually this answer should be broken in a few steps
1
THIS operator
it will refer to the current object/scope in which it is used
for eg:
say a button listener is made like this
new button(context).setOnClickListener(new View.onClickListener(public void onClick(View v){
//Using this here to refers to this onclicklistener
});
// for a constructor
public classname(int arg1){
//so to initialise the arg1 of yur class with this arg1
//for just thesake of.clarity you write
this.arg1=arg1;
}
2
this used here with the songlist is redundant and is of no signficance as ther e is no conflict.
Hope this helps you.

this keyword is used to refere to the current object
So you can access any member of current object using this.member. As in your example you are accesig songList within the current object so there is no difference between using this and not using this.
More use of this keyword
as you mentioned about the following example
private int a;
void method(int a){
this.a = a;
}
here this is used to refer to the member of current object as the names are same. if you used
void method(int b){
a = b;
}
then there would be no difference between using this and not using this
Some More Example
private int a = 5;
public void method() {
int a = 6;
System.out.println(a); // will print 6
System.out.println(this.a); // will print 5
}
int the following example the second one is pointing to the member variable of current object so it is printing 5.

Related

AsyncTaskLoader keeps reloading data when I come back to the MainActivity

I am quite new to the Android Development and I really need your help. My problem is in the MainActivity below. The app essentially displays a list of movies in the main activity and the movie details in another activity. And the problem is that whenever a user comes back from the MovieActivity to the MainActivity, the loader starts loading data again, although the movies are already there. And then it can not stop loading the data. It is really annoying. I want to get rid of this. So when a user comes back to the MainActivity, the loader will know that there is already loaded data and will not load anything again.If it helps, here is my full GitHub repo https://github.com/mateuszwojnarowicz/PopularMovies
I am stuck for about 3 weeks and have tried hundreds of possible solutions. Nothing seems to work. I feel really desperate.
Thank you so much for help,
Matthew
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<String> {
private MovieAdapter mAdapter;
private ArrayList<Movie> mMoviesCollection;
private SharedPreferences sharedPreferences;
private Resources resources;
private LoaderManager loaderManager;
private Loader<String> loader;
private RecyclerView.LayoutManager layoutManager;
private String sortBy;
#BindView(R.id.pb)
ProgressBar progressBar;
#BindView(R.id.er)
TextView errorTextView;
#BindView(R.id.rv)
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mMoviesCollection = new ArrayList<Movie>();
sharedPreferences = getSharedPreferences(Constants.SHARED_PREFS, Activity.MODE_PRIVATE);
resources = getResources();
sortBy = sharedPreferences.getString(Constants.KEY_SORT, null);
setSharedPref();
layoutManager = new GridLayoutManager(this, calculateNoOfColumns(this));
loaderManager = getLoaderManager();
loader = loaderManager.getLoader(Constants.LOADER_MOVIES_ID);
initialize();
makeOperationLoadMovies(sortBy);
}
public static int calculateNoOfColumns(Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
int noOfColumns = (int) (dpWidth / 150);
return noOfColumns;
}
//Set first-launch pref and set title according to pref
private void setSharedPref(){
if(!sharedPreferences.contains(Constants.KEY_SORT)) {
saveData(Constants.VALUE_POP);
setTitle(resources.getString(R.string.title_pop));
} else {
if (Objects.equals(sharedPreferences.getString(Constants.KEY_SORT, null), Constants.VALUE_POP)) {
setTitle(resources.getString(R.string.title_pop));
}
if (Objects.equals(sharedPreferences.getString(Constants.KEY_SORT, null), Constants.VALUE_TOP)) {
setTitle(resources.getString(R.string.title_top));
}
}
}
//Set up the RecyclerView
private void initialize(){
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
mMoviesCollection = new ArrayList<>();
mAdapter = new MovieAdapter(mMoviesCollection, this, this);
recyclerView.setAdapter(mAdapter);
}
private void makeOperationLoadMovies(String SORT_BY){
Bundle bundle = new Bundle();
bundle.putString(Constants.LOADER_MOVIES_EXTRA, SORT_BY);
if(recyclerView.isDirty()){
}
else if(loader==null){
loaderManager.initLoader(Constants.LOADER_MOVIES_ID, bundle, this);
}else{
loaderManager.restartLoader(Constants.LOADER_MOVIES_ID, bundle, this);
}
}
//Update shared pref
private void saveData(String SORT_VALUE){
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(Constants.KEY_SORT, SORT_VALUE);
editor.apply();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.menu_fav:
startActivity(new Intent(MainActivity.this, FavoritesActivity.class));
break;
case R.id.menu_pop:
saveData(Constants.VALUE_POP);
Toast.makeText(this, resources.getString(R.string.message_popularity),Toast.LENGTH_LONG).show();
break;
case R.id.menu_top:
saveData(Constants.VALUE_TOP);
Toast.makeText(this, resources.getString(R.string.message_rating),Toast.LENGTH_LONG).show();
break;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPause() {
super.onPause();
Parcelable recyclerViewState;
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();//save
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
#Override
protected void onPostResume() {
super.onPostResume();
Parcelable recyclerViewState;
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();//save
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
}
#SuppressLint("StaticFieldLeak")
#Override
public Loader<String> onCreateLoader(int id, final Bundle args) {
return new AsyncTaskLoader<String>(this) {
#Override
protected void onStartLoading() {
super.onStartLoading();
forceLoad();
progressBar.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.INVISIBLE);
}
#Override
public void deliverResult(String data) {
super.deliverResult(data);
}
#Override
public String loadInBackground() {
String jsonString = "";
URL url = NetworkUtils.buildUrl(args.getString(Constants.LOADER_MOVIES_EXTRA));
try {
jsonString += NetworkUtils.getResponseFromHttpUrl(url);
} catch (IOException e) {
e.printStackTrace();
}
if(jsonString.isEmpty()){
} else {
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(Constants.JSON_KEY_MOVIE_RESULTS);
for (int i = 0; i < jsonArray.length(); i++) {
//Get 1 movie from JSON
String mTitle;
int mId;
String mPosterUrl;
String mPlot;
double mUserRating;
String mReleaseDate;
JSONObject Jmovie = (JSONObject) jsonArray.get(i);
mTitle = Jmovie.getString(Constants.JSON_KEY_MOVIE_TITLE);
mId = Jmovie.getInt(Constants.JSON_KEY_MOVIE_ID);
mPosterUrl = NetworkUtils.getPosterString(Jmovie.getString(Constants.JSON_KEY_MOVIE_POSTER_PATH));
mPlot = Jmovie.getString(Constants.JSON_KEY_MOVIE_OVERVIEW);
mUserRating = Jmovie.getDouble(Constants.JSON_KEY_MOVIE_VOTE_AVERAGE);
mReleaseDate = Jmovie.getString(Constants.JSON_KEY_MOVIE_RELEASE_DATE);
//Get videos
ArrayList<Video> mVideos = new ArrayList<Video>();
URL videosURL = NetworkUtils.buildUrlVideos(String.valueOf(mId));
String videosJSON = NetworkUtils.getResponseFromHttpUrl(videosURL);
JSONObject jsonObjectVideos = new JSONObject(videosJSON);
JSONArray jsonArrayVideos = jsonObjectVideos.getJSONArray(Constants.JSON_KEY_VIDEO_RESULTS);
if(jsonArrayVideos.length()==0){
mVideos = null;
} else {
for(int v = 0; v < jsonArrayVideos.length(); v++){
JSONObject Jvideo = (JSONObject) jsonArrayVideos.get(v);
String mVideoName;
String mVideoUrlString;
mVideoName = Jvideo.getString(Constants.JSON_KEY_VIDEO_NAME);
mVideoUrlString = "https://www.youtube.com/watch?v="+Jvideo.getString(Constants.JSON_KEY_VIDEO_KEY);
Video video = new Video(mVideoName, mVideoUrlString);
mVideos.add(video);
}
}
//GetReviews
ArrayList<Review> mReviews = new ArrayList<Review>();
URL reviewsURL = NetworkUtils.buildUrlReviews(String.valueOf(mId));
String reviewsJSON = NetworkUtils.getResponseFromHttpUrl(reviewsURL);
JSONObject jsonObjectReviews = new JSONObject(reviewsJSON);
JSONArray jsonArrayReviews = jsonObjectReviews.getJSONArray(Constants.JSON_KEY_REVIEW_RESULTS);
if(jsonArrayReviews.length()!=0) {
for(int r = 0; r < jsonArrayReviews.length(); r++){
JSONObject Jreview = (JSONObject) jsonArrayReviews.get(r);
String mReviewName;
String mReviewText;
mReviewName = Jreview.getString(Constants.JSON_KEY_REVIEW_AUTHOR);
mReviewText = Jreview.getString(Constants.JSON_KEY_REVIEW_CONTENT);
Review review = new Review(mReviewName, mReviewText);
mReviews.add(review);
}
}
Movie movie = new Movie(mTitle, mId, mPosterUrl, mPlot, mUserRating, mReleaseDate, mVideos, mReviews);
mMoviesCollection.add(movie);
}
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
return null;
}
};
}
#Override
public void onLoadFinished(Loader<String> loader, String data) {
progressBar.setVisibility(View.GONE);
mAdapter.notifyDataSetChanged();
}
#Override
public void onLoaderReset(Loader<String> loader) {
}
}
Because you are new to Android there is a lot wrong. So, many people probably won't want to chime in. Regardless, I'm new as well and in the same class as you are right now, so I'll give it a shot.
First, your loader is not returning the correct data type. Your loader should be of Loader<List<Movie>> and it should return a new AsyncTaskLoader<List<Movie>>. The reason you want this is to make use of everything the AsyncTaskLoader has to offer. I'll explain further.
Second, we'll cache the data inside the loader by moving the initial reference from the Activity into the loader.
So move private ArrayList<Movie> mMoviesCollection; as an instance variable of your AsyncTaskLoader. Remove the line mMoviesCollection = new ArrayList<Movie>(); from both your onCreate and initialize methods.
In your AsyncTaskLoader, you need to check if your data exists already in your onStartLoading before forceLoad and implement deliverResult.
So, your onStartLoading() should look like this:
#Override
protected void onStartLoading() {
super.onStartLoading();
if(mMoviesCollection.isEmpty()){
forceLoad();
progressBar.setVisibility(View.VISIBLE);
errorTextView.setVisibility(View.INVISIBLE);
} else {
deliverResult(mMoviesCollection)
}
}
And your deliverResult should look like this:
#Override
public void deliverResult(List<Movie> data) {
mMoviesCollection = data;
super.deliverResult(data);
}
Now you need to implement a setData(List<Movie> movies) method that sets your adapter's data instance variable and calls notifyDataSetChanged() in your Adapter. Like so:
public void setData(List<Movie> movies){
mMovies = movies;
notifyDataSetChanged();
}
Get rid of the List<Movie> from your adapter's constructor. This way you can construct the adapter without any data. The adapter's getItemCount() should return 0 if the data is null and the recyclerView will not try to build the view.
With that done you can then call onLoadFinished like this:
#Override
public void onLoadFinished(Loader<List<Movie>> loader, List<Movie> data) {
progressBar.setVisibility(View.GONE);
mAdapter.setData(data);
}
EDIT: Made a correction to account for the ArrayList instantiating as an Instance variable. You can either not instantiate the mMoviesCollection there and then do so later or just check if its empty with mMoviesCollection.isEmpty() as I changed above in onStartLoading.:
EDIT:
You need to get your libraries straight, you are using android.app in some places and android.support in others.
So in your imports change these:
import android.app.LoaderManager;
import android.content.AsyncTaskLoader;
import android.content.Loader;
all to:
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
Now the TMDB.org API has a request limit of 40 requests per 10 seconds.
https://developers.themoviedb.org/3/getting-started/request-rate-limiting
Because of this, your Loader is not even completing everything and is throwing an exception. I would suggest breaking up when you call the videos and reviews into the MovieActivity by creating another AsyncTaskLoader there and calling each when the details screen loads.
You could also technically add a Thread.sleep(300) or less to your AsyncTaskLoader but it makes it seriously slow. In other words, you would have to push the data beyond the 10-second mark to load completely.
Now, with that and the changes we have made, everything does survive config changes such as screen rotation.
If you want the data to survive any further you will have to persist the data somehow. Like saving the json response as a string in onSaveInstanceState or saving the JSon String to the database you created.

How can I make sharedpreferences in Custom Adapter get the latest values of my ArrayList?

I use Volley in the onCreate of my Activity which gets a string on my server, then I convert this string to an arraylist,checkedContactsAsArrayList, and I pass it over to my custom adapter using sharedpreferences, which does stuff with the arraylist in the listview.
But the custom adapter keeps getting the previous arraylist in sharedpreferences, not the one I've just got from the server. The Volley call is too late or something - I can see in logcat the latest values are put after they are got, if you know what I mean.
For example:
VolleyCall 1 putString: 1,2,3
VolleyCall 2 putString: 4,5,6
VolleyCall 3 putString: 7,8,9
Custom Adapter 1 getString: gets values of the last time app was used
Custom Adapter 2 getString: 1,2,3
Custom Adapter 3 getString: 4,5,6
Any idea how to fix this? I could try doing the Volley call in the getView of my custom adapter but I've read on Stackoverflow that's bad practice.
Here are the relvant parts of my code - I've slimmed it down a bit, as there's a lot of stuff in there irrelevant to this issue.
Here's the code of my activity, ViewContact:
public class ViewContact extends AppCompatActivity implements android.widget.CompoundButton.OnCheckedChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_view_contact);
//selectPhoneContacts is an empty array list that will hold our SelectPhoneContact info
selectPhoneContacts = new ArrayList<SelectPhoneContact>();
listView = (ListView) findViewById(R.id.listviewPhoneContacts);
StringRequest stringRequest = new StringRequest(Request.Method.POST, ViewContact_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//toast the response of ViewContact.php, which has been converted to a
//JSON object by the Php file with JSON encode
Toast.makeText(ViewContact.this, "OnResponse is" + response, Toast.LENGTH_LONG).show();
System.out.println("ViewContact: And the response is " + response);
try {
//checkedContacts is a String
String checkedContacts = responseObject.getString("checkedcontacts");
//convert the checkedContacts string to an arraylist
checkedContactsAsArrayList = new ArrayList<String>(Arrays.asList(checkedcontacts.split(",")));
System.out.println("ViewContact: checkedContactsAsArrayList is " + checkedContactsAsArrayList);
//we want to bring the checkedContactsAsArrayList array list to our SelectPhoneContactAdapter.
// It looks like Shared Preferences
//only works easily with strings so best way to bring the array list in Shared Preferences is with
//Gson.
//Here, we PUT the arraylist into the sharedPreferences
SharedPreferences sharedPreferencescheckedContactsAsArrayList = PreferenceManager.getDefaultSharedPreferences(getApplication());
SharedPreferences.Editor editorcheckedContactsAsArrayList = sharedPreferencescheckedContactsAsArrayList.edit();
Gson gsoncheckedContactsAsArrayList = new Gson();
String jsoncheckedContactsAsArrayList = gsoncheckedContactsAsArrayList.toJson(checkedContactsAsArrayList);
editorcheckedContactsAsArrayList.putString("checkedContactsAsArrayList", jsoncheckedContactsAsArrayList);
editorcheckedContactsAsArrayList.commit();
System.out.println("ViewContact: jsoncheckedContactsAsArrayList is " + jsoncheckedContactsAsArrayList);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ViewContact.this, error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
//we are posting review_id into our ViewContact.php file, which
//we get when a row is clicked in populistolistview
//to get matching details
params.put("review_id", review_id);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//checkBoxforContact.setChecked(true);
}
//******for the phone contacts in the listview
// Load data in background
class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
//we want to delete the old selectContacts from the listview when the Activity loads
//because it may need to be updated and we want the user to see the updated listview,
//like if the user adds new names and numbers to their phone contacts.
selectPhoneContacts.clear();
SelectPhoneContact selectContact = new SelectPhoneContact();
selectContact.setName(phoneNameofContact);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new SelectPhoneContactAdapter(selectPhoneContacts, ViewContact.this,0);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
#Override
protected void onResume() {
super.onResume();
// getPrefs();
ViewContact.LoadContact loadContact = new ViewContact.LoadContact();
loadContact.execute();
Toast.makeText(ViewContact.this, "resuming!", Toast.LENGTH_SHORT).show();
}
}
And my custom adapter, SelectPhoneContactAdapter :
public class SelectPhoneContactAdapter extends BaseAdapter {
//define a list made out of SelectPhoneContacts and call it theContactsList
public List<SelectPhoneContact> theContactsList;
//define an array list made out of SelectContacts and call it arraylist
private ArrayList<SelectPhoneContact> arraylist;
Context _c;
ArrayList<String> MatchingContactsAsArrayList;
ArrayList<String> checkedContactsAsArrayList;
ArrayList <String> allNamesofContacts;
String contactToCheck;
//we will run through different logic in this custom adapter based on the activity that is passed to it
private int whichactivity;
String phoneNumberofContact;
String[] phoneNumberofContactStringArray;
String ContactsString;
Intent intent;
public SelectPhoneContactAdapter(final List<SelectPhoneContact> selectPhoneContacts, Context context, int activity) {
theContactsList = selectPhoneContacts;
_c = context;
this.arraylist = new ArrayList<SelectPhoneContact>();
this.arraylist.addAll(theContactsList);
whichactivity = activity;
//we are fetching the array list checkedContactsAsArrayList, created in ViewContact.
//with this we will put a tick in the checkboxes of contacts the review is being shared with
SharedPreferences sharedPreferencescheckedContactsAsArrayList = PreferenceManager.getDefaultSharedPreferences(_c);
Gson gsoncheckedContactsAsArrayList = new Gson();
String jsoncheckedContactsAsArrayList = sharedPreferencescheckedContactsAsArrayList.getString("checkedContactsAsArrayList", "");
Type type2 = new TypeToken<ArrayList<String>>() {
}.getType();
checkedContactsAsArrayList = gsoncheckedContactsAsArrayList.fromJson(jsoncheckedContactsAsArrayList, type2);
System.out.println("SelectPhoneContactAdapter checkedContactsAsArrayList :" + checkedContactsAsArrayList);
}
}
#Override
public int getCount() {
return arraylist.size();
}
#Override
public Object getItem(int i) {
return arraylist.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
static class ViewHolder {
//In each cell in the listview show the items you want to have
//Having a ViewHolder caches our ids, instead of having to call and load each one again and again
TextView title, phone;
CheckBox check;
Button invite;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//this is the SelectPhoneContact object; consists of textboxes, buttons, checkbox
final SelectPhoneContact data = (SelectPhoneContact) arraylist.get(i);
ViewHolder holder = null;
if (convertView == null) {
//if there is nothing there (if it's null) inflate the view with the layout
LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.phone_inflate_listview, null);
holder = new ViewHolder();
//So, for example, title is cast to the name id, in phone_inflate_listview,
//phone is cast to the id called no etc
holder.title = (TextView) convertView.findViewById(R.id.name);
holder.phone = (TextView) convertView.findViewById(R.id.no);
holder.invite = (Button) convertView.findViewById(R.id.btnInvite);
holder.check = (CheckBox) convertView.findViewById(R.id.checkBoxContact);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//in the listview for contacts, set the name
holder.title.setText(data.getName());
//in the listview for contacts, set the number
holder.phone.setText(data.getPhone());
holder.check.setTag(data);
return convertView;
}
}
Call this: loadContact.execute();
After you call .commit();
ViewContact.LoadContact loadContact = new ViewContact.LoadContact();
loadContact.execute();

Passing value from ListView to another Activity/Class [duplicate]

This question already has answers here:
How to pass an object from one activity to another on Android
(35 answers)
Closed 6 years ago.
So here I have class ListProductActivity.java that display list of products based on the search criteria entered by user and the data are retrieve from MySQL server using Json. My question is, how can I pass a single value (productName in this case) when user select from the listview to another activity so that I can use that value in the new Activity (viewProductActivity.java).
ListProductActivity.java
public class ListProductActivity extends AppCompatActivity {
private ListView list;
private ProgressDialog loading;
ArrayList<HashMap<String, String>> productList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_product);
list = (ListView) findViewById(R.id.listView);
productList = new ArrayList<HashMap<String,String>>();
getData();
}
public void getData(){
String s = getIntent().getStringExtra("productName");
loading = ProgressDialog.show(this,"Please wait...","Fetching...",false,false);
String url = Config.DATA_URL2 + s;
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
showList(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ListProductActivity.this,error.getMessage().toString(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showList(String response){
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray products = jsonObject.getJSONArray(Config.JSON_ARRAY);
for(int i=0;i<products.length();i++){
JSONObject productData = products.getJSONObject(i);
String name = productData.getString(KEY_NAME);
String price = productData.getString(KEY_PRICE);
String brand = productData.getString(KEY_BRAND);
HashMap<String,String> product = new HashMap<String,String>();
product.put(KEY_NAME,name);
product.put(KEY_PRICE,price);
product.put(KEY_BRAND,brand);
productList.add(product);
}
ListAdapter adapter = new SimpleAdapter(
ListProductActivity.this, productList, R.layout.list_product,
new String[]{KEY_NAME,KEY_PRICE,KEY_BRAND},
new int[]{R.id.name, R.id.price, R.id.brand}
);
list.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
So, what function can I implement in my ListProductActivity class to pass the productName based on user selected in the listView to another activity and how to receive the passing value in viewProductActivity class?
I really hope you guys can post the function and briefly explain on how it works, so that I can understand the codes really well. Comment at the codes will be more clear and helpful. Thank You.
Edited
Here is the picture of the result from the listview after searching
Click To View Image
First simply implement onItemClickListener of listview on current activity
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String product_name = productList.get(position).get(KEY_NAME);
Intent intent = new Intent(YourCurrentActivity.this,YourNextActivity.class);
intent.putExtra("product_name",product_name);
startActivity(intent);
}
});
and receive that value in onCreate method of YourNextActivity.java like this:
Bundle bundle = getIntent().getExtras();
String productname = bundle.getString("product_name");
Implement like this,
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String name = productList.get(position).get(KEY_NAME);
Intent i;
i = new Intent(mContext, viewProductActivity.class);
i.putExtra("productName",name);
startActivity(i);
}
});
Pass the array list to the new activity later you can use whatever you want from that extra
eg:-
Intent i = new Intent(ctx, SecondActivity.class);
i.putExtra("List", List); //List is an arraylist like yours
startActivity(i);
Second activity:
SList = (ArrayList<HashMap<String,String>>) getIntent().getSerializableExtra("List");
Now use whatever you want using SList.get(0).get("keyname")
put your code here
private void showList(String response){
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray products = jsonObject.getJSONArray(Config.JSON_ARRAY);
for(int i=0;i<products.length();i++){
JSONObject productData = products.getJSONObject(i);
String name = productData.getString(KEY_NAME);
String price = productData.getString(KEY_PRICE);
String brand = productData.getString(KEY_BRAND);
HashMap<String,String> product = new HashMap<String,String>();
product.put(KEY_NAME,name);
product.put(KEY_PRICE,price);
product.put(KEY_BRAND,brand);
productList.add(product);
}
ListAdapter adapter = new SimpleAdapter(
ListProductActivity.this, productList, R.layout.list_product,
new String[]{KEY_NAME,KEY_PRICE,KEY_BRAND},
new int[]{R.id.name, R.id.price, R.id.brand}
);
list.setAdapter(adapter);
// put your new code here
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String product_name = productList.get(position).get(KEY_NAME);
Intent intent = new Intent(YourCurrentActivity.this,YourNextActivity.class);
intent.putExtra("product_name",product_name);
startActivity(intent);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
You can pass it via Intent in your listview adapter as
Intent i;
i = new Intent(mContext, viewProductActivity.class);
i.putExtra("productName",whateverstring);
mContext.startActivity(i);

How do I iteratively add to a List on button click in java?

I want to add values to an array/list and then store these in shared preferences, to then display on another activity.
When I try my code it only seems to save the first value, and if I add more it just overwrites the value.
I do not want to create the List each time I click the button so I have put it at the very beginning.
If there isn't an existing value then the message should be added to the List and stored in shared preferences as Status_0, if there is an existing value then it should be added as Status_1 - but it's not. I think it is because it is not saving properly in the List but I'm not sure how to do that.
Here's my code:
public class EnterReadingsActivity extends AppCompatActivity implements View.OnClickListener {
private EditText erTemperatureEditText;
private Button erSubmitBtn;
public List<String> values = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_enterreadings);
init();
}
private void init() {
erTemperatureEditText = (EditText) findViewById(R.id.erTemperatureEditText);
erSubmitBtn = (Button) findViewById(R.id.erSubmitBtn);
erSubmitBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (view.getId()==R.id.erSubmitBtn) {
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
String message = erTemperatureEditText.getText().toString();
editor.putInt("Status_size", values.size());
int status_size = values.size();
for (int i = status_size; i < status_size + 1; i++) {
editor.putString("Status_" + i, message);
values.add(message);
editor.commit();
}
}
}
}
Edit:
int status_size = values.size();
for(int i = 0; i < status_size + 1; i++)
{
String value = values.get(i);
if (value != null) {
values.add(value);
status_size++;
String textView_i = "textView" + i;
TextView textView_i = new TextView(this);
textView_i.setLayoutParams(new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
ActionBar.LayoutParams.WRAP_CONTENT));
textView_i.setText(value);
historyBackgroundInside.addView(textView_i);
}
}
It is incorrect to use the sharedPreferences to pass data from one activity to another.
The data are usually entered into an object (Bundle) which will be passed in the intent and then taken up in the next activity.
another way is to use the extras that works like Bundle
public class EnterReadingsActivity extends AppCompatActivity implements View.OnClickListener {
private EditText erTemperatureEditText;
private Button erSubmitBtn;
public List<String> values = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_enterreadings);
init();
}
private void init() {
erTemperatureEditText = (EditText) findViewById(R.id.erTemperatureEditText);
erSubmitBtn = (Button) findViewById(R.id.erSubmitBtn);
erSubmitBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (view.getId()==R.id.erSubmitBtn) {
String message = erTemperatureEditText.getText().toString();
values.add(message);
}
//Here you should enter the condition that allows you to
//call the method to go to the next activity
//ex: click of a button, I have the list reaches a size
//Add a example code
if (values.size() == 10) {
passDataAndGoInAnotherActivity();
}
}
public void passDataAndGoInAnotherActivity () {
Intent i = new Intent (this, NameOfYouNextActivity.class);
i.putExtra("status_list", values);
// Or use Bundle
// Bundle bundle = new Bundle();
// bundle.putSerializable("status_list", values);
// i.putExtra("bundle", values)
startActivity(i)
}
}
to take in the other activity values using this code
public class NameOfYourNextActivity extends AppCompatActivity {
public List<String> values;
public ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_nameoflayout);
listview = (ListView) findViewById(R.id.listView);
Intent intent = getIntent();
//If you first method
if (intent != null && intent.hasExtra("status_list")) {
List<String> values = (List<String>)intent.getSerializableExtra("status_list")
}
//If you second method (Bundle)
// if (intent != null && intent.hasExtra("Bundle")) {
// Bundle bundle = intent. getBundleExtra("Bundle")
// if (bundle != null && bundle.containsKey("status_list")) {
// List<String> values = (List<String>)intent.getSerializableExtra(String name)
// }
if (values != null) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
listview.setAdapter(adapter);
}
}
}
I did the update of the code to give you a solution that comes close to what you need..
Remember to create the next activity and insert it in the manifest.
Change the name of the class based on your activity and enter the correct layout name.
Remember to include in your layout a list view (change id in my code) that will allow you to print your values.
In this example it uses a simple adapter with a layout provided by Android, but you can create something custom.
Here you will find an excellent guide

Data is not populating in list, Android

I am trying to populate fragment listview using async task,
But listvew is not populating. I am getting data in logs, And there is no error and exception in logs.
I am following this example
dynamic listview adding "Load more items" at the end of scroll
Here is code:-
public class HindiFragment extends Fragment {
// XML node keys
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
static final String KEY_VIDEO_URL = "video";
static final String KEY_UPLOAD_BY = "upload_by";
Context abc=null;
static int startIndex = 0;
private WeakReference<MyAsyncTask> asyncTaskWeakRef;
ListView list;
static LazyAdapter adapter;
JSONObject json;
static int offset = 10;
static ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
public static Context hindiFragment=null;
private static int catId=0;
static View rootView ;
public HindiFragment(){}
public HindiFragment(int position) {
// TODO Auto-generated constructor stub
catId=position;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
//StrictMode.setThreadPolicy(policy);
rootView = inflater.inflate(R.layout.main, container, false);
// TextView tvLabel = (TextView)rootView.findViewById(R.id.txtLabel);
// tvLabel.setText("Hello"); try
hindiFragment=rootView.getContext();
try{
//Toast.makeText(hindiFragment, "catid is "+catId,
// Toast.LENGTH_LONG).show();
UserFunctions userFunction = new UserFunctions();
json=userFunction.getAndroidVersion();
JSONArray android_version_array = json.getJSONArray("version");
TextView tv = (TextView) rootView.findViewById(R.id.android_version);
//getting android version
for (int i = 0; i < android_version_array.length(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
JSONObject myObj = android_version_array.getJSONObject(i);
if(! myObj.getString("version").equalsIgnoreCase(String.valueOf(getString(R.string.android_version)))){
tv.setText( Html.fromHtml(myObj.getString("text")));
tv.setMovementMethod(LinkMovementMethod.getInstance());
}else
{
tv.setVisibility(View.GONE);
}
// adding each child node to HashMap key => value
}
startNewAsyncTask(this.getActivity());
return rootView;
}catch(Exception e){
e.printStackTrace();
}
return rootView;
}
public static void loadMore(int startIndex,int page,Activity myActivity){
try{
UserFunctions userFunction = new UserFunctions();
Log.e("page ",""+page);
int status=0;
JSONObject json;
json = userFunction.getChannelData(String.valueOf(catId),page);
if(json.has("video")){
JSONArray deletedtrs_array = json.getJSONArray("video");
for (int i = 0; i < deletedtrs_array.length(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
JSONObject myObj = deletedtrs_array.getJSONObject(i);
// adding each child node to HashMap key => value
map.put(KEY_ID, myObj.getString("uid"));
map.put(KEY_TITLE, myObj.getString("uid"));
map.put(KEY_ARTIST,myObj.getString("video"));
map.put(KEY_DURATION, myObj.getString("duration"));
map.put(KEY_THUMB_URL,myObj.getString("thumb_url"));
map.put(KEY_VIDEO_URL, myObj.getString("url"));
map.put(KEY_UPLOAD_BY,"By: "+ myObj.getString("upload_by"));
// adding HashList to ArrayList
//if(!songsList.contains(map))
{
songsList.add(map);
status=1;
}
}
}
//if(status==1)
{
//]list=(ListView)rootView.findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
// adapter=new LazyAdapter(myActivity, songsList);
// list.setAdapter(adapter);
// adapter.notifyDataSetChanged();
}
}catch(Exception e){
e.printStackTrace();
}
}
private void startNewAsyncTask(Activity act) {
MyAsyncTask asyncTask = new MyAsyncTask(act);
this.asyncTaskWeakRef = new WeakReference<MyAsyncTask >(asyncTask );
asyncTask.execute();
}
private static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
private WeakReference<HindiFragment> fragmentWeakRef;
HindiFragment uindiFragment;
Activity myActivity;
private MyAsyncTask (Activity activity) {
this.fragmentWeakRef = new WeakReference<HindiFragment>(uindiFragment);
myActivity=activity;
}
#Override
protected Void doInBackground(Void... params) {
//Toast.makeText(hindiFragment, "helllo",
// Toast.LENGTH_LONG).show();
//TODO: your background code
Log.e("Now in background",offset+"");
loadMore(startIndex, offset,myActivity);
return null;
}
#Override
protected void onPostExecute(Void response) {
super.onPostExecute(response);
ListView list=(ListView)rootView.findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(myActivity, songsList);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
Log.e("Ended here11 ","now endeded11");
if (this.fragmentWeakRef.get() != null) {
//TODO: treat the result
adapter.notifyDataSetChanged();
}
}
}
}
You are over-using weak reference. My guess is your async task or fragment is being garbage collected since you use them cyclically: you can verify this by seeing if weakReference.get() returns null.
In fact, you don't need WeakReference at all: just implement appropriate cancel logic that you can call from onPause onStop or onDestroy depending on how you want to handle repeated calls.
Also you shouldn't pass the context to your Async class: instead create an observer such as:
public interface Callback {
public void onAsyncDone(Arraylist<DataItem> listItems);
}
and if not cancelled,
#Override public void onPostExecute(Void v) {
if (!isCancelled()) {
Callback c = callbackReference.get();
if (c != null) c.onAsyncDone(getListItems());
}
}
where getListItems() returns whatever work is done in doInBackground. Here I use a weak reference for the callback (which you implement in your activity) since you seem to want to use one. But again, as long as you release the reference to the context if cancelled, you don't actually need one. The reason the activity is wrapped as the Callback is that the async task should only have one job: process the items and pass them along. Let your activity or controller change the UI with the new items.
I suspect the loadMore() method does not load up any data to object songsList into the adapter. Simply trace the reason why it is not. There's no way I can debug this without using debugger, the code flow is rather complicated with unusually tight references and, more so, with static access.
The suspected code for review:
protected void onPostExecute(Void response) {
super.onPostExecute(response);
ListView list=(ListView)rootView.findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(myActivity, songsList);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
...
}
Note: You can put some good logging in LazyAdapter code and see if data is populated there.

Categories