Android - Adding objects to a list view from another activity - android

I've got a custom list view with my own adapter. I can add objects to this list within the same activity, but what I want to do is add objects from another activity. In this other activity there are two Edit Text boxes. One is responsible for Main text, second for Description, and two radio buttons that are determining image. At the bottom is Add button, that should add entered data to the list view.
I tried to do this with Parcelable, but I don't know exactly how to implement it. Below is my ListView class:
public class Activity_4 extends AppCompatActivity {
private ListView listView;
private myAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_4);
listView = (ListView)findViewById(R.id.listView4);
ArrayList<Object> objectList = new ArrayList<>();
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
objectList.add(new Object(R.drawable.row_img, "After Earth" , "2013"));
mAdapter = new myAdapter(this,objectList);
listView.setAdapter(mAdapter);
}
public class Object implements Parcelable {
int imageID;
String mainText;
String description;
public Object (int imageID, String mainText, String description) {
this.imageID = imageID;
this.mainText = mainText;
this.description = description;
}
public Object() {
}
public int getImageID() {
return imageID;
}
public void setImageID(int imageID) {
this.imageID = imageID;
}
public String getMainText () {
return mainText;
}
public void setMainText() {
this.mainText = mainText;
}
public String getDescription() {
return description;
}
public void setDescription() {
this.description = description;
}
public Object(Parcel in) {
this.imageID = in.readInt();
this.mainText = in.readString();
this.description = in.readString();
}
public final Parcelable.Creator<Object> CREATOR = new Parcelable.Creator<Object>() {
#Override
public Object createFromParcel(Parcel in) {
return new Object(in);
}
#Override
public Object[] newArray(int size) {
return new Object[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(imageID);
dest.writeString(mainText);
dest.writeString(description);
}
}
public class myAdapter extends ArrayAdapter<Object> {
private Context mContext;
private List<Object> objectList = new ArrayList<>();
public myAdapter(#NonNull Context context, ArrayList<Object> list) {
super(context,0,list);
mContext = context;
objectList = list;
}
#NonNull
#Override
public View getView (int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View listItem = convertView;
if (listItem == null)
listItem = LayoutInflater.from(mContext).inflate(R.layout.list_row, parent, false);
Object currentObject = objectList.get(position);
ImageView image = (ImageView) listItem.findViewById(R.id.row_image);
image.setImageResource(currentObject.getImageID());
TextView mainTxt = (TextView) listItem.findViewById(R.id.row_tv1);
mainTxt.setText(currentObject.getMainText());
TextView description = (TextView) listItem.findViewById(R.id.row_tv2);
description.setText(currentObject.getDescription());
return listItem;
}
}
Can anyone help with this problem?
Thanks

You can other Activity using startActivityForResult() and pass data in bundle as result on click of add button from other Activity, so current activity will add the data to it's list.
Calling Other Activity to add
startActivityForResult(intent,reqCode);
On Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == reqCode) {
Object object = new Object();
object.setImageID(data.getIntExtra("image_id"));
object.setMainText(data.getStringExtra("main_text");
object.setDescription(data.getStringExtra("desc");
objectlist.add(object);
mAdapter.notifyDataSetChanged();
}
}
Other Activity
public void onAddClick(){
Intent intent = new Intent();
intent.putIntExtra("image_id",*<value>*);
intent.putStringExtra("main_text",*<value>*);
intent.putStringExtra("desc",*<value>*);
setResult(intent);
finish();
}

A good starting point might be to start your EditText activity using startActivityForResult and pass the updates to the list to your adapter through the result, after you added everything you wanted by calling setResult with your new data. For further reference see Getting a Result from an Activity. Good luck!

When opening 2nd Activity from 1st Activity
do
Intent mIntent=new Intent(this,YourSecondActivity.class);
startActivityForResult(mIntent,SOME_STATIC_INT)
In another activity
on click of AddButton
Intent mIntent=new Intent(this,YourFirstActivity.class);
mIntent.putExtra("DATA",Object)
setResult(SOME_STATIC_INT,mIntent)
now in 1st Activity
Override onActivity Result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data != null && requestCode == SOME_STATIC_INT) {
Object object = data.getParcelableExtra("DATA")
objectlist.add(object);
mAdapter.notifyDataSetChanged();
}
}

Related

Android: Why the listview.add function is always adding elements on position 1 in the list

I am trying to implement two activities that are exchanging information between them using intents.
Activity#1 contains an empty listview and a button that starts Activity#2 when pressed. On Activity#2 I have some textbox fields and a "Save" button that sends through intent.putExtra methods information to Activity#1.
The issue is that each time I try to create a new View with the information passed by Activity#2, the list is overriding the first element.
You can see below the OnCreate method from Activity#1:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_explorer);
notesList = findViewById(R.id.listviewNotes);
FloatingActionButton myFab = this.findViewById(R.id.fabAddNote);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentNoteEditor = new Intent(getApplicationContext(), NoteEditor.class);
startActivity(intentNoteEditor);
//Log.i("Lista",notesList.getCount()+"");
}
});
Intent intent =getIntent();
Bundle extras =intent.getExtras();
if(extras!=null){
if(extras.containsKey("isnewNote")){
isnewElement=extras.getBoolean("isnewNote",false);
}
}
if(isnewElement==true){
//***************Fetch data from intent***************//
notetext = intent.getStringExtra("noteText");
notecolor = intent.getStringExtra("noteColor");
notelocation = intent.getStringExtra("noteLocation");
notereminder = intent.getStringExtra("noteReminder");
Note receivednote = new Note(notetext, notecolor, notereminder, notelocation);
MyAdapter adapter = new MyAdapter(this, R.layout.list_item, notesArray);
notesArray.add(receivednote);
notesList.setAdapter(adapter);
//***************End Fetch data from intent***********//
}
}
I am also attaching the custom adapter implemented.
public class MyAdapter extends ArrayAdapter {
private Context mContext;
private int mResource;
private ArrayList<Note> mNotes = new ArrayList<>();
private String TAG = "Adapter Class";
public MyAdapter(#NonNull Context context, int resource, ArrayList<Note> objects) {
super(context, resource, objects);
mContext = context;
mResource = resource;
mNotes = objects;
}
#Override
public int getCount() {
return mNotes.size();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItem =convertView;
if(listItem==null){
listItem=LayoutInflater.from(mContext).inflate(mResource,parent,false);
Note currentNote = mNotes.get(position);
String text = mNotes.get(position).getText();
String color = mNotes.get(position).getColor();
String location = mNotes.get(position).getLocation();
String reminder = mNotes.get(position).getReminder();
TextView nttxt = listItem.findViewById(R.id.noteText);
TextView ntcolor = listItem.findViewById(R.id.textcolor);
TextView ntrem = listItem.findViewById(R.id.reminder);
TextView ntlocat = listItem.findViewById(R.id.location);
nttxt.setText(text);
ntcolor.setText(color);
ntrem.setText(reminder);
ntlocat.setText(location);
}
return listItem;
}
}
I logged the list size and it is always 1. For some reason, it does not keep the current elements after the Activity#2 is launched.
Any advice will be appreciated.
The problem is that every time you press the "Save" button in Activity#2 you are launching a new instance of Activity#1 hence the single note in the list. You need to use the startActivityForResult() method when launching Activity2 and then override onActivityResult() in order to get the data returned data. Activity#1 can look like this:
public static final int NEW_NOTE_REQUEST = 23;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_explorer);
notesList = findViewById(R.id.listviewNotes);
FloatingActionButton myFab = this.findViewById(R.id.fabAddNote);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intentNoteEditor = new Intent(getApplicationContext(), NoteEditor.class);
startActivityForResult(intentNoteEditor, NEW_NOTE_REQUEST);
//Log.i("Lista",notesList.getCount()+"");
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check the returned result and parse the data
if(resultCode == RESULT_OK && requestCode == NEW_NOTE_REQUEST){
notetext = intent.getStringExtra("noteText");
notecolor = intent.getStringExtra("noteColor");
notelocation = intent.getStringExtra("noteLocation");
notereminder = intent.getStringExtra("noteReminder");
Note receivednote = new Note(notetext, notecolor, notereminder, notelocation);
MyAdapter adapter = new MyAdapter(this, R.layout.list_item, notesArray);
notesArray.add(receivednote);
notesList.setAdapter(adapter);
}
}
And then in Activity#2:
public void onSaveButtonClick(View view) {
Intent intent = new Intent();
// Add note data to intent
// return the result to Activity#1
setResult(RESULT_OK, intent);
finish();
}
You can also achieve the same function by creating a shared data repository, like a singleton class that will hold your notes list and both the activities will have a reference to the same notes list.

How to load a title and image from a ListView to a Detail_Activity using a if/else statement?

I have a ListView developed in Android Studio, I have a few items that will go to a specific activity however the majority of the items will go to a Detail_Activity. The problem that I am having is that I don't know how to get the image and title text from the ListView to display on the Detail_Activity. Can someone explain how I can make this happen? Thanks
I have tried to use the code that I developed as shown but it will not display the image or name on the Detail_Activity when the row is clicked.
Here is the code minus all the list items in MainActivity.java:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.list_view);
final ArrayList<Object> list = new ArrayList<>();
list.add(new String("Government Codes"));
list.add(new LTCItem("Reciprocity", "Agreements With Other States", R.drawable.handshake));
listView.setAdapter(new LTCAdapter(this, list));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 1) {
Intent intent = new Intent(MainActivity.this, Activity1.class);
startActivity(intent);
}
if (position == 2) {
Intent intent = new Intent(MainActivity.this, Activity2.class);
startActivity(intent);
} else {
Intent intent = new Intent(MainActivity.this, Detail.class);
startActivity(intent);
}
}
});
}
}
Here is the code from the Detail_Activity.java file:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class Detail extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
}
Here is the code from the Item.java file:
public class LTCItem {
private String name;
private String subtitle;
private int image;
public LTCItem(String name, String subtitle, int image) {
this.name = name;
this.subtitle = subtitle;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
}
Here is the code from the Adapter.java file:
public class LTCAdapter extends BaseAdapter {
ArrayList<Object> list;
private static final int LTC_Item = 0;
private static final int HEADER = 1;
private LayoutInflater inflater;
public LTCAdapter(Context context, ArrayList<Object> list) {
this.list = list;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getItemViewType(int position) {
if (list.get(position) instanceof LTCItem) {
return LTC_Item;
} else {
return HEADER;
}
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int i) {
return list.get(i);
}
#Override
public long getItemId(int i) {
return 1;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
switch (getItemViewType(i)) {
case LTC_Item:
view = inflater.inflate(R.layout.item_list_view, null);
break;
case HEADER:
view = inflater.inflate(R.layout.item_listview_header, null);
break;
}
}
switch (getItemViewType(i)) {
case LTC_Item:
ImageView image = (ImageView) view.findViewById(R.id.itemListViewImgIcon);
TextView name = (TextView) view.findViewById(R.id.itemListViewTxtTopicName);
TextView subtitle = (TextView) view.findViewById(R.id.itemListViewTxtTopicSubtitle);
image.setImageResource(((LTCItem) list.get(i)).getImage());
name.setText(((LTCItem) list.get(i)).getName());
subtitle.setText(((LTCItem) list.get(i)).getSubtitle());
break;
case HEADER:
TextView title = (TextView) view.findViewById(R.id.itemListViewHeader);
title.setText(((String) list.get(i)));
break;
}
return view;
}
}
I expect the Detail_Activity to display name, image from the ListView when clicked, and I will add a description text to the Detail_Activity as well.
for this, you just have to pass your data using intent put extra methods like this in the first activity
Intent = intent = new Intent(this , Detail.class)
intent.putString("name",list.get(position).getName());
intent.putString("image",list.get(position).getImage());
startctivity(intent)
Now just get your data in the Detail activity's onCreatae method just like this
if(getIntent().getExtras()!=null){
String namae = getIntent().getStringExtra("name");
String image= getIntent().getStringExtra("image");
}
Now you can use your image or name where you want to use them
You should add it in intent extra
From main activity:
Intent i = new Intent(MainActivity.this, DetailActivity.class);
i.putExtra("title",list.get(position).getTitle)
startActivity(i);
In detail activity:
String title = getIntent().getStringExtra("title");

ListView Adapter setResult() and Finish() error

I want to startActivity for Result by using startActivityForResult() method.Now the activity which get started has a listview with adapter class for it.I had wriiten following Listview Adapter so when user selects any item it should return back to calling activity with selected item name.I cant able to call 2 methods
setResult() and finish() in following code
Adapter Code:
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefernces = mContext.getSharedPreferences("MyKey111", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1 = prefernces.edit();
editor1.putString("Custname",customerpopulationlist.get(position).getName());
editor1.putString("let_id", customerpopulationlist.get(position).getLetId());
editor1.commit();
Intent intentMessage = new Intent();
// put the message in Intent
intentMessage.putExtra("MESSAGE", "hello");
intentMessage.putExtra("selected_refer", customerpopulationlist.get(position).getLetId());
setResult(RESULT_OK, intentMessage);
finish();
}
});
you must hold an reference to your activity that created the adapter then set result to that. the thing you are doing is setting the result of OnClickListener object !!
add an Activity object to your adapter constructor and save it in a local variable in adapter and call it act then call the setResult() of the activtiy like below:
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
SharedPreferences prefernces = mContext.getSharedPreferences("MyKey111", Context.MODE_PRIVATE);
SharedPreferences.Editor editor1 = prefernces.edit();
editor1.putString("Custname",customerpopulationlist.get(position).getName());
editor1.putString("let_id", customerpopulationlist.get(position).getLetId());
editor1.commit();
Intent intentMessage = new Intent();
// put the message in Intent
intentMessage.putExtra("MESSAGE", "hello");
intentMessage.putExtra("selected_refer", customerpopulationlist.get(position).getLetId());
//THESE TWO LINES NEED TO BE CHANGED
act.setResult(RESULT_OK, intentMessage);
act.finish();
}
});
You need override method protected void onActivityResult(int requestCode, int resultCode, intent data on the activity you need to return to i.e. the activity where you have called startActivityforResult().
#override
protected void onActivityResult(int requestCode, int resultCode, intent data){
if(resultCode == -1) // -1 for RESULT_OK
{ // your logic goes here...
}
}
There is difference between an Activity object and A Context object(if there is confusion, better read the documentation for better understanding) So, the answer is simple,
When you want to do an activity based operation, follow like this
Activity activity = this;
Context context = ActivityName.this;
Pass both the objects in the adapter and then use
activity.setResult(Activity.RESULT_OK,intent);
activity.finish();
and for context-based operations use Intent i = new Intent( ListViewAdapter.this.mContext,EventPrivacyAndTicketPrice.class);
see full activity code below:
public class ActivityX extends AppCompatActivity {
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_x);
intent = getIntent();
ListView listView = findViewById(R.id.list_x);
ArrayList<ETypeObject> allTypes= new ArrayList<>();
allTypes = GetData();
ListViewAdapter listViewAdapter= new ListViewAdapter(allTypes,ActivityX.this,intent,this);
listView.setAdapter(listViewAdapter);
}
public ArrayList<ETypeObject> GetData(){
ArrayList<ETypeObject> allTypes= new ArrayList<>();
allTypes.add(new ETypeObject("Object1",0));
allTypes.add(new ETypeObject("Object2, Talk",0));
allTypes.add(new ETypeObject("Object3",0));
return allTypes;
}
}
class ETypeObject {
public String name;
public int imageId;
public ETypeObject(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public ETypeObject() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
}
class ListViewAdapter extends BaseAdapter{
Activity activity;
Context mContext;
ArrayList<ETypeObject> allTypes= new ArrayList<>();
Intent intent;
public ListViewAdapter(){}
public ListViewAdapter(ArrayList<ETypeObject> AllTypes, Context context,Intent intent,Activity activity){
mContext = context;
allTypes = AllTypes;
activity =activity;
this.intent = intent;
}
#Override
public int getCount() {
return allTypes.size();
}
#Override
public Object getItem(int i) {
return allTypes.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i1, View view, ViewGroup viewGroup) {
LayoutInflater layoutInflater= (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (layoutInflater!=null){
view = layoutInflater.inflate(R.layout.lay1,null);
}
TextView type;
type = view.findViewById(R.id.parentInteresttext);
type.setText(allTypes.get(i1).getName());
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Toast.makeText(mContext,allTypes.get(i1).getName(),Toast.LENGTH_LONG).show();
if (intent.getBooleanExtra("fromThirdActivty",false)){
Intent i = new Intent();
i.putExtra("eventType",allTypes.get(i1).getName());
activity.setResult(Activity.RESULT_OK,intent);
activity.finish();
}
Intent i = new Intent( ListViewAdapter.this.mContext,OtherActivity.class);
i.putExtra("eventType",allTypes.get(i1).getName());
ListViewAdapter.this.mContext.startActivity(i);
}
});
return view;
}
}

how to add a Custom adapter to listview in android

This is my code to scan a near by bluetooth device but when i add a custom adapter to it it throwing an error..
public class MainActivity extends Activity {
ListView listDevicesFound;
Button btnScanDevice;
BluetoothAdapter bluetoothAdapter;
int REQUEST_CODE = 1;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnScanDevice = (Button)findViewById(R.id.scan);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
listDevicesFound = (ListView)findViewById(R.id.list);
listDevicesFound.setAdapter(adapter);
CheckBlueToothState();
btnScanDevice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
adapter.clear();
if(bluetoothAdapter.startDiscovery())
{
Toast.makeText(getBaseContext(),"Scanning", Toast.LENGTH_LONG).show();
}
}
});
registerReceiver(ActionFoundReceiver,new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
#Override
protected void onDestroy() {
super.onDestroy();unregisterReceiver(ActionFoundReceiver);
}
private void CheckBlueToothState()
{
if (bluetoothAdapter == null)
{
Toast.makeText(getBaseContext(),"Bluetooth Not Supported",Toast.LENGTH_LONG).show();
}
else
{
if (bluetoothAdapter.isEnabled())
{
if(bluetoothAdapter.isDiscovering())
{
Toast.makeText(getBaseContext(),"Bluetooth is currently in device discover process",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getBaseContext(),"Bluetooth is Enabled",Toast.LENGTH_LONG).show();
btnScanDevice.setEnabled(true);
}
}
else
{
Toast.makeText(getBaseContext(), "Bluetooth is not Enabled", Toast.LENGTH_LONG).show();
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_CODE);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_CODE)
{
CheckBlueToothState();
}
}
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
adapter.add(device.getName() + "\n" + device.getAddress());
adapter.notifyDataSetChanged();
}
}};
}
Custom adapter
public class MyAdapter extends ArrayAdapter<BlueDevices>
{
Context context;
int resources;
ArrayList<BlueDevices> Devices = null;
public MyAdapter(Context context, int resource,ArrayList<BlueDevices> Devices) {
super(context, resource, Devices);
this.context=context;
this.resources=resource;
this.Devices=Devices;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView textView = new TextView(getContext());
BlueDevices item = getItem(position);
textView.setTextColor(Color.BLACK);
textView.setText(item.Name+" : "+item.Mac +" date :"+item.getDateFormatted());
return textView;
}
public List<BlueDevices> getAllItem() {
List<BlueDevices> result = new ArrayList<>();
for (int i = 0; i < getCount(); i++) {
Log.e("fef", "getAllItem: " );
result.add(getItem(i));
}
return result;
}
}
BlueDevice:
public class BlueDevices {
public String Name;
public String Mac;
public Date date;
public BlueDevices(String Name)
{
this.Name=Name;
this.Mac=Mac;
this.date=date;
}
private SimpleDateFormat format = new SimpleDateFormat("dd MMMM yyyy");
public String getDateFormatted() {
if (date == null){
return " no date ";
}
return format.format(date);
}
}
this line throwing an error adapter.add(device.getName() + "\n" + device.getAddress());
There are many problems in your code.
Change in Bean file BlueDevices
change constructor to take two arguments.
public BlueDevices(String Name, String Mac)
{
this.Name=Name;
this.Mac=Mac;
}
you no need to set data because you already created method to get data.
change in onCreate method in activity class
In your adapter class constructor take three arguments.
MyAdapter(Context context, int resource,ArrayList<BlueDevices> Devices);
so you have context that get from getApplicationContext(), resource is your layout and Devices is arraylist of your bean class. for that you have to create one layout in your res/layout and one ArrayList with bean typecase.
ArrayList<BlueDevices> list = new ArrayList<>();
add your all devices in to this list using.
list.add(new BlueDevices("Device1","ASDF234SDFSADF"));
list.add(new BlueDevices("Device2","GSDFG34SAF32DF"));
Now create object of adapter class
MyAdapter adapter = new MyAdapter(getApplicationContext(),R.layout.list_items,list);
set this adapter to your ListView using
listview.setAdapter(adapter);
Now create method in adapter class
public BlueDevices getDevices(int position) {return Devices.get(position);}
Add getter method in BlueDevices
public String getName(){
return Name;
}
public String getMac(){
return Mac;
}
Get devices list from adapter in list onItemClickListener
BlueDevices bean = adapter.getDevices(position);
String name = bean.getName();
String mac = bean.getMac();

How to pass values from RecycleAdapter to MainActivity or Other Activities

I am working on a shopping cart app,Items are displayed as below.There is a plus, minus (+/-) buttons to choose the number of quantity.
If product quantity is changed, I need to pass "productname" and "quantity" to the main activity so that I could use them to prepare final cart. I got some suggestions to use database or some content providers,
I am not sure how to do it.., please help
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecycleAdapter recycleAdapter;
List<HashMap<String, String>> onlineData;
ProgressDialog pd;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyle_view);
toolbar= (Toolbar) findViewById(R.id.anim_toolbar);
setSupportActionBar(toolbar);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
final String url = "http://www.qa4.org/?json=get_recent_posts&count=45";
new AsyncHttpTask().execute(url);
}
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
#Override
protected void onPreExecute() {
pd=new ProgressDialog(MainActivity.this);
pd.requestWindowFeature(Window.FEATURE_NO_TITLE);
pd.setMessage("Loading please wait...");
pd.setCancelable(false);
pd.show();
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
e.printStackTrace();
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
pd.dismiss();
if (result == 1) {
recycleAdapter = new RecycleAdapter(MainActivity.this,onlineData);
recyclerView.setAdapter(recycleAdapter);
} else {
Toast.makeText(MainActivity.this, "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.optJSONArray("posts");
onlineData = new ArrayList<>();
for (int i = 0; i < posts.length(); i++) {
JSONObject post = posts.optJSONObject(i);
HashMap<String, String> item = new HashMap<>();
item.put("title", post.optString("title"));
JSONArray jsonArray = post.getJSONArray("attachments");
JSONObject jsonObject1 = jsonArray.getJSONObject(0);
JSONObject jsonArrayImages = jsonObject1.getJSONObject("images");
JSONObject jsonArrayThumb = jsonArrayImages.getJSONObject("thumbnail");
item.put("thump", jsonArrayThumb.optString("url"));
onlineData.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
RecycleAdapter.java
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolderRec> {
List<HashMap<String, String>> onlineData;
SQLiteDatabase db;
Context context;
RecycleAdapter(Context context,List<HashMap<String, String>> onlineData){
this.onlineData = onlineData;
this.context=context;
}
#Override
public ViewHolderRec onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolderRec( LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycle, parent, false));
}
#Override
public void onBindViewHolder(ViewHolderRec holder, int position) {
HashMap<String,String> map =onlineData.get(position);
//Download image using picasso library
Picasso.with(context).load(map.get("thump"))
.error(R.drawable.placeholder)
.placeholder(R.drawable.placeholder)
.into(holder.iv);
holder.tv.setText(map.get("title"));
}
#Override
public int getItemCount() {
return onlineData.size();
}
public class ViewHolderRec extends RecyclerView.ViewHolder implements View.OnClickListener{
ImageView iv;
TextView tv, quantity;
ImageView Add_Cart;
ImageView Remove_Cart;
public ViewHolderRec(View itemView) {
super(itemView);
iv = (ImageView) itemView.findViewById(R.id.thumbnail);
tv = (TextView) itemView.findViewById(R.id.title);
quantity = (TextView)itemView.findViewById(R.id.cart_qty);
Add_Cart = (ImageView)itemView.findViewById(R.id.cart_add);
Remove_Cart = (ImageView)itemView.findViewById(R.id.cart_remove);
itemView.setOnClickListener(this);
Add_Cart.setOnClickListener(this);
Remove_Cart.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v.getId() == Add_Cart.getId()){
increment();
}
else if(v.getId() == Remove_Cart.getId()){
decrement();
}
}
public void increment(){
int currentNos = Integer.parseInt(quantity.getText().toString()) ;
quantity.setText(String.valueOf(++currentNos));
}
public void decrement(){
int currentNos = Integer.parseInt(quantity.getText().toString()) ;
quantity.setText(String.valueOf(--currentNos));
}
}
}
How to do this,
You should create interface, and activity implements this interface.
public interface OnItemClick {
void onClick (String value);
}
When you create adapter (last parameter is this interface)
public class MainActivity extends AppCompatActivity implements OnItemClick {
recycleAdapter = new RecycleAdapter(MainActivity.this,onlineData, this);
recyclerView.setAdapter(recycleAdapter);
#Override
void onClick (String value){
// value this data you receive when increment() / decrement() called
}
// In Adapter
private OnItemClick mCallback;
RecycleAdapter(Context context,List<HashMap<String, String>> onlineData,OnItemClick listener){
this.onlineData = onlineData;
this.context = context;
this.mCallback = listener;
}
....
public void increment(){
int currentNos = Integer.parseInt(quantity.getText().toString()) ;
quantity.setText(String.valueOf(++currentNos));
mCallback.onClick(quantity.getText().toString());
}
public void decrement(){
int currentNos = Integer.parseInt(quantity.getText().toString()) ;
quantity.setText(String.valueOf(--currentNos));
mCallback.onClick(quantity.getText().toString());
}
I failed to do it with both Interface and Observer pattern. But Local Broadcast worked for me.
In Adapter
String ItemName = tv.getText().toString();
String qty = quantity.getText().toString();
Intent intent = new Intent("custom-message");
// intent.putExtra("quantity",Integer.parseInt(quantity.getText().toString()));
intent.putExtra("quantity",qty);
intent.putExtra("item",ItemName);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Main Activity
public void onCreate(Bundle savedInstanceState) {
...
// Register to receive messages.
// We are registering an observer (mMessageReceiver) to receive Intents
// with actions named "custom-message".
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-message"));
}
...
public BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String ItemName = intent.getStringExtra("item");
String qty = intent.getStringExtra("quantity");
Toast.makeText(MainActivity.this,ItemName +" "+qty ,Toast.LENGTH_SHORT).show();
}
};
Three popular ways to solve this problem
Interfaces
Phuoc Huynh has already explained how to use interfaces to solves this.
Observer pattern.
Try googling around observer to understand how it works. We will register the classes who want to receive events with the type of events they want to receive. There will be a manager classes to manage registering and unregistering of receivers and also to send the events to all receivers
public class EventManager {
private static EventManager eventManager;
private static Object syncObject = new Object();
private HashMap<String, ArrayList<EventListener>> listeners = new HashMap<>();
private EventManager(){}
public static EventManager getInstance() {
if (eventManager == null) {
synchronized (syncObject) {
if (eventManager == null) {
eventManager = new EventManager();
}
}
}
return eventManager;
}
public synchronized void registerListener(String event, EventListener listener) {
if (listeners.containsKey(event)) {
listeners.get(event).add(listener);
} else {
ArrayList<EventListener> arrayList = new ArrayList<>();
arrayList.add(listener);
listeners.put(event, arrayList);
}
}
public synchronized void unRegisterListener(String event, EventListener listener) {
if (listeners.containsKey(event)) {
listeners.get(event).remove(listener);
if (listeners.get(event).size() == 0) {
listeners.remove(event);
}
}
}
public void sendEvent(String event, Object o) {
if (listeners.containsKey(event)) {
ArrayList<EventListener> listener = listeners.get(event);
for (EventListener eventListener : listener) {
eventListener.onEvent(o);
}
}
}
}
Your MainActivity will register itself as a receiver of increment and decrement events and also implement onEvent method of IEventListener
public class MainActivity extends AppCompatActivity implements IEventListener{
#Override
protected void onCreate(Bundle onSavedInstanceState) {
EventManager.getInstance().registerEvent("increment", this);
EventManager.getInstance().registerEvent("decrement", this)
}
#Override
public void onEvent(String event) {
if (event.equals("increment") {
//increment
} else if (event.equals("decrement") {
//decrement
}
}
#Override
protected void onDestroy() {
EventManager.getInstance().unRegisterEvent("increment", this);
EventManager.getInstance().unRegisterEvent("decrement", this)
}
}
In you adapter class send the events
EventManager.getInstance().sendEvent("increment");
EventManager.getInstance().sendEvent("decrement");
LocalBroadcasts
LocalBroadcasts works the same way as the above example. you have get Instance of LocalBroadcastManger and send Broadcast on it. Define a broadcast receiver in the onCreate of the activity and register it using registerReceiver() in the Activity. Pass an intent filter in the register receiver with actiontype same as the broadcasts you want your activity to receive. Make sure you unregister the broadcasts whenever you don't need them or in the onDestroy of the activity
Simple solution using interface:
Create an interface with method containing objects/data as parameters:
public interface RecyclerViewDataPass {
public void pass(String productName, String quantity);
}
Implement interface method in Activity & pass it through RecyclerView Adapter:
RecyclerViewDataPass recyclerViewDataPass = new RecyclerViewDataPass() {
#Override
public void pass(String productName, String quantity) {
//we get data from adapter here
//assign parameters to activity variables or do the needed operations
}
};
recycleAdapter = new RecycleAdapter(MainActivity.this,onlineData,recyclerViewDataPass);
recyclerView.setAdapter(recycleAdapter);
Edit adapter's constructor:
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolderRec> {
List<HashMap<String, String>> onlineData;
SQLiteDatabase db;
Context context;
RecyclerViewDataPass recyclerViewDataPass; //here is our data pass object
RecycleAdapter(Context context,List<HashMap<String, String>> onlineData, RecyclerViewDataPass recyclerViewDataPass){
this.onlineData = onlineData;
this.context=context;
this.recyclerViewDataPass=recyclerViewDataPass; //get data pass object from activity
}
Inside RecyclerView Adapter call pass function to send data to activity:
recyclerViewDataPass.pass(tv.getText().toString(), quantity.getText().toString());
Check out this. It works for me.
Just Paste in Your Activity or Fragment
rvSelectedProductList = Recyclerview
selcetedItemAdapter = RecyclerView Adapter
rvSelectedProductList.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final int itemCount = selectedItemAdapter.getItemCount();
for (int i = 0; i < itemCount; i++) {
TextView tvSelling = rvSelectedProductList.getChildAt(i).findViewById(R.id.tvSelling);
TextView textViewDrawerTitle = rvSelectedProductList.getChildAt(i).findViewById(R.id.tvCartQty);
String totalamount = tvSelling.getText().toString();
String qty = textViewDrawerTitle.getText().toString();
System.out.println("qty" + qty);
System.out.println("total" + totalamount);
}
rvSelectedProductList.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
//Simply it works for me
//In onBindViewHolder of RecyclerAdapter write the following code on clickEvent of any view;
Intent intent = new Intent(tContext, TargetActivity.class);
intent.putExtra("key", "value");
tContext.startActivity(intent);
//TargetActivity.java
String str = getIntent().getStringExtra("key");
//You got the value as String :)
add these codes in onBindViewHolder
Intent intent = new Intent("message_subject_intent");
intent.putExtra("name" , String.valueOf(messageSubject.getname()));
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Add on MainActivity
public BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String name= intent.getStringExtra("name");
Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
}
};
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,new IntentFilter("message_subject_intent"));

Categories

Resources