Pass data from RecyclerView Adaptor to another activity - java

I have created a RecyclerView which populates the users' contacts with a checkbox.
When a user clicks on a checkbox, I want to add that contact to an Object.
Now I have been able to do that, but I am facing issues with sending that object from the adapter to another activity:
#Override
public void onBindViewHolder(ViewHolder holder, final int position){
// final PlayerDetails thePlayer = playerData.get(position);
// ArrayList<PlayerDetails> thePlayer = playerData;
//holder.playerNameNumber.setText(thePlayer.name + " " + thePlayer.number);
holder.playerNameNumber.setText(playerData.get(position).name +playerData.get(position).number );
holder.pickedPlayer.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View thisView){
PlayerDetails contact = new PlayerDetails();
contact.number = playerData.get(position).name;
contact.name = playerData.get(position).number;
playerListGame.addPlayer(contact);
String name = playerData.get(position).name;
Toast.makeText(thisView.getContext(),name + " added",Toast.LENGTH_LONG).show();
}
});
}
When I debug the above, I can see playerListGame contains the data I am adding to it.
Now, I tried to do the following :
public PlayerList donePickingSendPlayers(){
return playerListGame;
}
at the bottom of my adapter.
But when I debug, it shows that it has a value of 0. (I did initialise it at the start.
How can I send playerListGame to another activity?
I have set up a floating button, which onClick does the following:
private void donePicking(){
ContactPickerRecyclerViewAdapter justToGetPlayerData = new ContactPickerRecyclerViewAdapter();
justToGetPlayerData.donePickingSendPlayers();
Intent backToComposeMessage = new Intent(this,ComposeMessage.class);
startActivity(backToComposeMessage);
}
But that doesn't seem to work as the playerListGame within "donePickingPlayers"
is empty.

use the same object of adapter you have set in recyclerview while fetching data using your method created inside adapter.
private void donePicking(){
ContactPickerRecyclerViewAdapter justToGetPlayerData = new
ContactPickerRecyclerViewAdapter();
justToGetPlayerData.donePickingSendPlayers();
Intent backToComposeMessage = new Intent(this,ComposeMessage.class);
startActivity(backToComposeMessage);
}
in this method you are creating another instance of the adapter class which always gives you empty data.

Write an interface with method donePicking(PlayerDetails contact) in your adapter and implement that method in your activity and override method in your activity there you'll get PlayerDetails object in overridden method and you can pass it to next activity.

Related

on ListView item click, move Google Map camera to the specified marker

I have a Google Maps activity that includes a search box and a List View of Deliveries (which hold LatLng). When I click on an address inside of the List view, I want the camera to move to that address/marker (all Addresses inside the ListView are marked).
I have this method inside of my custom ListAdapter where I tried to get Update the Camera, but it doesn't work. Here's part of my code.
public class DeliveriesListAdapter extends ArrayAdapter<Delivery> implements View.OnClickListener {
private ArrayList<Delivery> deliveries;
public DeliveriesListAdapter(ArrayList<Delivery> data, Context context) {
super(context, R.layout.activity_row_item, data);
this.deliveries = data;
this.mContext = context;
}
#Override
public void onClick(View v) {
// TODO: on click, move camera to selected address on map.
int position = (Integer) v.getTag();
Delivery delivery = (Delivery) deliveries.get(position);
CameraUpdateFactory.newLatLng(delivery.getLatLng());
}
}
The List at the bottom of the screen is supposed to move the camera to that marker on the map.
Here's My Data class that holds the LatLng of the specified list item.
public class Delivery {
private String address;
private double distance, time;
private LatLng latLng;
private Place place;
public Delivery(Place place) {
address = place.getAddress().toString();
distance = -1;
time = -1;
latLng = place.getLatLng();
this.place = place;
}
Inside of my Google Maps activity:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback{
private ArrayList<Delivery> deliveryList = new ArrayList<>();
// called inside onCreate(...)
private void setUpListView() {
deliveriesListView = findViewById(R.id.deliveries_listview);
adapter = new DeliveriesListAdapter(addressList, this);
deliveriesListView.setAdapter(adapter);
}
/**
* Used to add Delivery to a list view.
* #param delivery The Delivery containing the address to be added to the view to add the marker.
*/
private void addDeliveryToList(Delivery delivery) {
deliveryList.add(delivery);
adapter.notifyDataSetChanged();
}
edit: I know that CameraUpdateFactory.newLatLng(delivery.getLatLng()); was wrong, I was messing with it earlier and deleted what I had originally.
SOLUTION: I managed to solve it by rewriting my custom list adapter to be a RecyclerViewAdapter, and managed to move the Overriden onClick method to my Maps Activity, which was what I was having trouble doing.
You also need to tell map to move camera. Like this mMap.moveCamera(CameraUpdateFactory.newLatLng(delivery.getLatLng())). And one more thing, you should neveer handle clicks in the adapter. They ought to be contained in the host UI part. You can use interface to have callback in the host UI part. You can get hint on how to do this here.
In your onCLick function, replace CameraUpdateFactory.newLatLng(delivery.getLatLng()); by animateCamera(CameraUpdateFactory.newLatLng(delivery.getLatLng())

How to send and receive ArrayList<String> using Intent?

I am new in Android. I need your help. My Problem is - I have 2 classes Nplist.java and Addcustomer.java. In my AddCustomer class,One TextView and one Button is there to go Nplist class. In my Nplist class there is checklist and this checklist is coming from database and all the checked values are stored in ArrayList<String> and one Button is used to go back to AddCustomer class. I want that ArrayList<String> which is in Nplist to by display in my AddCustomer class Textview . I haved tried these but my Addcustomer class crashed.
1.Nplist.class
add.setOnClickListener(new View.OnClickListener() {<br>
#Override<br>
public void onClick(View view) {<br>
Bundle extra=new Bundle();<br>
extra.putSerializable("objects",checkedList);<br>
Intent intent = new Intent(Nplist.this, AddCustomer.class);<br>
intent.putExtra("extra",extra);<br>
startActivity(intent);<br>
});
2.AddCustomer.class
onCrete()...{
Bundle extra = getIntent().getBundleExtra("extra");<br>
ArrayList<String> object = (ArrayList<String>)extra.getSerializable("objects");<br>
for (String str : object) {<br>
getnp.append(str + "\n");<br>
}
}
What do you expect the result to be?
- What is the actual result you get? (Please include any errors.)
When i go like this Nplist-->AddCustomer its working well but crash on ( AddCustomer-->Nplist-->AddCustomer)
It's because when you are coming back to your AddCustomer Activity the list is null . You can solve this problem by making a global class which will store the list in a Static Field , And You can access that list from any class or Activity you want to. Try out below solution .
Global.java Class is as below :
public class Global {
private static ArrayList<String> object = new ArrayList<>();
public static ArrayList<String> getObject() {
return object;
}
public static void setObject(ArrayList<String> object) {
Global.object = object;
}
}
From NpList.java class set the value of the list as below :
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Global.setObject(checkedList);
Intent intent = new Intent(Nplist.this, AddCustomer.class);
startActivity(intent);
}
});
Now Access in AdCustomer.java as below :
onCreate()...{
Bundle extra = getIntent().getBundleExtra("extra");
ArrayList<String> object = Global.getObject();
for (String str : object) {
getnp.append(str + "\n");
}
}
This maybe helpful for you.
Using putStringArrayListExtra method you can send an array list of strings along with the intent.
Sender side:
Intent intent = ...
intent.putStringArrayListExtra("THE_KEY", theList);
Receiver side:
ArrayList<String> theList = intent.getStringArrayListExtra("THE_KEY");

How to pass object through activities by reference?

this is my first post here so be gentle :p
Here is the thing, I'm facing a really though issue and after several research i did not manage to figure out a clean solution. Let me explain:
I'm actually developing an android app for restaurant management.
In activity A, i'm able to create some articles with different parameters (picture, name, price ..).
I can also create a menu in which i indicate which articles are included. To do so i run Activity B that contains a dynamic list of the available articles (the ones i created) to be chosen. After picking up some of them the customised chosen objects are sent to Activity A through Parcel. And the chosen article list is updated in the menu.
But here is the thing, as far as i know, using Parcels create another instance of the object. As a result, if i modify or delete an article, the article list included in the menu does not change, and obviously i would like the list in the menu to be automatically updated.
Is there a way to simply pass customised objects through activities by reference?
What could be a clean solution to make the article list in the menu dynamic?
Here is some code:
In Activity A, in the menu interface i click + button to add an article, which run Activity B (the extras is the list of articles already included in the menu before, so in the beginning it's empty).
//Add article
FloatingActionButton addArticleButton = (FloatingActionButton)parentActivity.findViewById(R.id.addArticleButton);
addArticleButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showMenuDetails(menuListView,menuAdapter,currentMenu);
parentActivity.startActivityForResult(new Intent(parentActivity.getApplicationContext(),ChooseArticleActivity.class).putParcelableArrayListExtra("menuArticleList",currentMenu.getArticles()),PICK_ARTICLES);
}
});
In activity B: I select Articles in a list of available Articles (the ones i created). After picking up i press OK button to put the list of chosen articles in result Intent as Parcelable Extras
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.choose_article_layout);
initializeLists();
this.resultIntent = new Intent();
}
private void initializeLists(){
final ListView articleToChoose = (ListView)findViewById(R.id.articleToChoose);
final ListView articleChosen = (ListView)findViewById(R.id.articleChosen);
final ArrayList<Article> articleToChooseList = (ArrayList<Article>)MainActivity.model.getArticleList().getArticleList().clone();
final ArrayList<Parcelable> articleChosenListParcelable = (ArrayList<Parcelable>)this.getIntent().getParcelableArrayListExtra("menuArticleList");
final ArticleAdapter articleToChooseAdapter = new ArticleAdapter(getApplicationContext(), articleToChooseList);
articleToChoose.setAdapter(articleToChooseAdapter);
ArrayList<Article> articleChosenListTemp = new ArrayList<>();
ArrayList<Article> articleToRemove = new ArrayList<>();
for(Parcelable a:articleChosenListParcelable){
articleChosenListTemp.add((Article)a);
for(Article article:articleToChooseList){
if(article.getName().equals(((Article) a).getName())){
articleToRemove.add(article);
}
}
}
articleToChooseList.removeAll(articleToRemove);
articleToChooseAdapter.notifyDataSetChanged();
final ArrayList<Article> articleChosenList = articleChosenListTemp;
final ArticleAdapter articleChosenAdapter = new ArticleAdapter(getApplicationContext(),articleChosenList);
articleChosen.setAdapter(articleChosenAdapter);
articleChosen.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Article articleClicked = articleChosenAdapter.getItem(position);
articleChosenList.remove(articleClicked);
articleToChooseList.add(articleClicked);
articleChosenAdapter.notifyDataSetChanged();
articleToChooseAdapter.notifyDataSetChanged();
}
});
articleToChoose.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Article articleClicked = articleToChooseAdapter.getItem(position);
if(!articleChosenList.contains(articleClicked)){
articleChosenList.add(articleClicked);
articleToChooseList.remove(articleClicked);
articleToChooseAdapter.notifyDataSetChanged();
articleChosenAdapter.notifyDataSetChanged();
}
}
});
Button okButton = (Button)findViewById(R.id.okButton);
okButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chosenArticleListAttr = articleChosenList;
resultIntent.putParcelableArrayListExtra("articleList",chosenArticleListAttr);
setResult(RESULT_OK,resultIntent);
finish();
}
});
Button cancelButton = (Button)findViewById(R.id.cancelButton);
cancelButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
In activity A, in onActivityResult i catch the result and update the list, but the added Articles here are not the same instance as the article list in the model
if(requestCode==PICK_ARTICLES && resultCode==RESULT_OK){
ArticleAdapter articleAdapter = (ArticleAdapter) gestionMenusLayout.getMenuArticleListView().getAdapter();
ArrayList<Parcelable> chosenArticleList = (ArrayList<Parcelable>)data.getParcelableArrayListExtra("articleList");
gestionMenusLayout.getCurrentMenu().getArticles().clear();
for(Parcelable a:chosenArticleList){
gestionMenusLayout.getCurrentMenu().addArticle((Article)a);
}
articleAdapter.notifyDataSetChanged();
}
For debugging purpose only, I suggest that you use a public static List<Article> articleList and call it directly from whether activity A or B
A better but take-alittle-more-effort solution is that you store the list in a database, and every updates, queries, ... come through it.You can use the server's database (where people usually get articles from), or a offline database like Realm here
I figured it out with a quite easy and simple solution finally.
I keep passing my Article objects through intents by parcels.
But as it creates a new instance, instead of adding this instance i add the original one (the one from the model) after an equality key check (the name of the article). By doing so i keep the reference on my Article.
Thank you for helping!
Edit:
Here is the code:
if(requestCode==PICK_ARTICLES && resultCode==RESULT_OK){
ArticleAdapter articleAdapter = (ArticleAdapter) gestionMenusLayout.getMenuArticleListView().getAdapter();
ArrayList<Parcelable> chosenArticleList = (ArrayList<Parcelable>)data.getParcelableArrayListExtra("articleList");
gestionMenusLayout.getCurrentMenu().getArticles().clear();
ArrayList<Article> modelArticles = MainActivity.model.getArticleList().getArticleList();
for(Parcelable a:chosenArticleList){
for(Article modelArticle:modelArticles){
if(((Article)a).getName().equals(modelArticle.getName())){
gestionMenusLayout.getCurrentMenu().addArticle(modelArticle);
}
}
}
articleAdapter.notifyDataSetChanged();
}

Im missing some global variables

I've got 2 activities and a class that extends Application where I'm trying to store global variables with a kind of setter getter functions.
The main activity sets some views and a chart; then calls the second activity which should be setting values to be used afterwards on the previous chart.
Then pressing backbutton and returning to the previous activity onRestart is called and the chart is refreshed.
The problem is I lose my theorically global variables somewhere. Debugging i realized that the functions work perfectly fine while im adding values in the second activity but when I return to the first activity globalXCount returns '0' again. Why is that?
I think im missunderstanding some point regarding lifecycles.
I attach some fragments of the code.
First activity:
public class MainActivity extends Activity {
Global glObj = new Global();
CombinedChart mChart;
private int itemcount;
float displayed;
private final List<String> mMonthList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
mChart = (CombinedChart) findViewById(R.id.mchart);
populateHeaderList();
setChartSettings();
Intent intent = new Intent(MainActivity.this, QandA.class);
startActivity(intent);
}
#Override
protected void onRestart() {
super.onRestart();
itemcount = ((Global) this.getApplication()).getGlobalXCount();
displayed = itemcount/20;
populateHeaderList();
setChartSettings();
}
Second activity:
public class QandA extends Activity {
Global glObj = new Global();
ViewFlipper flipper;
private float lastX;
...
}else{
//TODO If all information if correctly filled
trainedmins = et1.getText().toString();
localLineValue = Integer.parseInt(trainedmins) * Integer.parseInt(statusQ1);
//Add values to lines
glObj.setLineXvalues(localLineValue);
// TODO Add new Bar value //
//Add 1 more value to count
glObj.addGlobalXCount();
}
...
Global class:
public class Global extends Application {
//TODO
public Integer globalXCount;
private List<Integer> lineXvalues = new ArrayList<>();
private List<Integer> barXvalues = new ArrayList<>();
//////
public Integer getGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
return this.globalXCount;
}else{
return this.globalXCount;
}
}
public void addGlobalXCount() {
if (this.globalXCount == null){
this.globalXCount = 0;
}else{
this.globalXCount = this.globalXCount + 1;
}
}
Thanks in advance.
First of all, register your custom Application context in AndroidManifest.xml within the <application>-tag.
<application
android:name="<your_package>.Global" ...>
Access the global application context within your activities like this:
Global glObj = (Global) getApplicationContext();
glObj.addGlobalXCount();
Do not create a new instance with new! Always retrieve the instance via getApplicationContext().
Furthermore, I would suggest you to initialize your class field glObj within the onCreate()-method of your Activities.

Android : how to set DropDown View Resource for Spinner?

I wrote a code for Spinner to bind array of USA States with Spinner in Android. But the problem is it shows reference type data in Spinner item, see the pic
I add android.R.layout.simple_spinner_dropdown_item but not know that what to add in layout. I checked many exemples on google and they add simple_spinner_dropdown_item but i could not find that what to add in layout. below is output and code. I want to show states in list instead of this junky data.
Spinner spStates = new Spinner(this);
spStates.setLayoutParams(new LayoutParams(screenWidth, LayoutParams.WRAP_CONTENT));
final USAStates states[] = new USAStates[51];
states[0] = new USAStates("Alabama", "AL");
states[1] = new USAStates("Alaska", "AK");
states[2] = new USAStates("Arizona", "AZ");
ArrayAdapter<USAStates> adapter = new ArrayAdapter<USAStates>(this, android.R.layout.simple_spinner_item, states);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spStates.setAdapter(adapter);
spStates.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
USAStates d = states[position];
Toast.makeText(getApplicationContext(), d.getStateAbrivation(), Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> parent) {
}
});
public class USAStates {
private String _Statename;
private String _StateAbrivation;
public USAStates(String pStatename, String pStateAbrivation) {
Statename(pStatename);
StateAbrivation(pStateAbrivation);
}
public void Statename(String pStatename) {
_Statename = pStatename;
}
public void StateAbrivation(String pStateAbrivation) {
_StateAbrivation = pStateAbrivation;
}
public String getStatename() {
return _Statename;
}
public String getStateAbrivation() {
return _StateAbrivation;
}
}
Not sure, just doing this off the top of my head but, in your USAState class override your toString method.As is it maybe that the adapter is using the default toString() hence your weird text displaying (which I presume is the class name of the USAStates class)
for example
#Override
public String toString(){
return _Statename
}
I originally accepted the toString() answer but have since found that this doesn't appear to be right.
I had an ActionBar with spinner/drop down list and my adapter items were rendering with String.toString() value instead of of the title I set in the custom adapter. Adding toString() did fix initially until I tried to set a compound drawable in the same layout.
I needed to override getDropDownView as well as getViewin my adapter.
Having to override toString() is symptomatic that you haven't overridden the right methods in your adapter.
When overriding getDropDownView having to override toString() is no longer required and everything works as expected.
And the answer on the following post is a great way to implement by using the super method:
alternating colors of spinner items

Categories

Resources