How to improve classes ? Issue with inner classes [Android] - java

I'm using Android Studio to develop my app. I have two activities that does the same thing (except a parameter value) and I have an inner class inside which does the same thing too in the other activity. My inner class extends AsyncTask for background downloading. But, if I extend my second activity from my 1st activity, I can't do task.execute(), I will need to extend AyncTask too,and extending from two classes impossible in Java.. Here's my code :
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private TextView title;
private List<User> myList;
String query_url;
MyAdapter myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycler = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager llm = new LinearLayoutManager(this);
llm.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(llm);
//create and execute new task
AsyncDL task = new AsyncDL();
task.execute();
}
//background download
private class AsyncDL extends AsyncTask<Object, String, Integer> {
#Override
protected Integer doInBackground(Object... params) {
tryDownloadXmlData();
return null;
}
private void tryDownloadXmlData() {
try {
URL xmlUrl = new URL(query_url);
myXMLPullParser myCustomParser = new myXMLPullParser();
//fetch & parse data
myList = myCustomParser.parse(xmlUrl.openStream());
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Integer integer) {
myAdapter = new MyAdapter(getApplicationContext(), myList);
recycler.setAdapter(myAdapter);
RecyclerItemClickSupport.addTo(recycler).setOnItemClickListener(new RecyclerItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
User user = myList.get(position);
Intent myIntent = new Intent(getApplicationContext(), Details.class);
myIntent.putExtra("user", user);
startActivity(myIntent);
}
});
super.onPostExecute(integer);
}
}
}
I don't really know if it is possible to reuse an activity's code like that, thanks !
EDIT: new piece of code
ProductAsyncTask task = new ProductAsyncTask(getApplicationContext(), listview, QUERY_URL, productList, myCustomAdapter);
task.execute();
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
User currentUser = myList.get(position); //error here
Intent myIntent = new Intent(getApplicationContext(), Detail_User.class);
myIntent.putExtra("currentUser", currentUser);
Log.i("INFO", "Loading extra data for transfer...");
startActivity(myIntent);
}
});

Related

How to getItemCount() when using FirestoreRecyclerAdapter because it always return 0?

I'm currently building a booking application for laundry's machine. I need to get the item count and if the count is zero it will show the dialog box which told user that there is no data in the system.
The Activity code:
public class DobbySelection2 extends AppCompatActivity {
String local;
private Dialog dialog;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private DobbyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dobby_selection2);
dialog = new Dialog(this);
dialog.setContentView(R.layout.custom_dialog2);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
dialog.getWindow().setBackgroundDrawable(getDrawable(R.drawable.custom_dialogbackground));
}
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialog.setCancelable(false); //Optional
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; //Setting the animations to dialog
Button Yes = dialog.findViewById(R.id.btn_yes);
Yes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(DobbySelection2.this, MainActivity.class );
dialog.dismiss();
startActivity(intent);
}
});
setUpRecyclerView();
}
private void setUpRecyclerView(){
Intent i = getIntent();
local = i.getStringExtra("PLACE");
if (local == null){
local = "Selangor";
}
CollectionReference dobbyRef = db.collection("locality")
.document(local)
.collection("Dobby");
Query query = dobbyRef.orderBy("name", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Dobby> options = new FirestoreRecyclerOptions.Builder<Dobby>()
.setQuery(query, Dobby.class)
.build();
adapter = new DobbyAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
//recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setLayoutManager(new CustomLinearLayoutManager(this));
recyclerView.setAdapter(adapter);
if(adapter.getItemCount() == 0){
dialog.show();
}
adapter.setOnItemClickListener(new DobbyAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
Dobby dobby = documentSnapshot.toObject(Dobby.class);
String id = documentSnapshot.getId();
Toast.makeText(DobbySelection2.this, "ID : " + id, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(DobbySelection2.this, Booking2.class);
intent.putExtra("PLACE", local);
intent.putExtra("ID", id);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
Adapter code:
public class DobbyAdapter extends FirestoreRecyclerAdapter<Dobby, DobbyAdapter.DobbyHolder>{
private OnItemClickListener listener;
/**
* Create a new RecyclerView adapter that listens to a Firestore Query. See {#link
* FirestoreRecyclerOptions} for configuration options.
*
* #param options
*/
public DobbyAdapter(#NonNull FirestoreRecyclerOptions<Dobby> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull DobbyHolder holder, int position, #NonNull Dobby model) {
holder.textViewName.setText(model.getName());
holder.textViewAddress.setText(model.getAddress());
holder.textViewDistance.setText(model.getDistance());
}
#NonNull
#Override
public DobbyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemdobby, parent, false);
return new DobbyHolder(v);
}
class DobbyHolder extends RecyclerView.ViewHolder{
TextView textViewName;
TextView textViewAddress;
TextView textViewDistance;
public DobbyHolder(#NonNull View itemView) {
super(itemView);
textViewName = itemView.findViewById(R.id.nameDobby);
textViewAddress = itemView.findViewById(R.id.addressDobby);
textViewDistance = itemView.findViewById(R.id.distanceDobby);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION && listener != null){
listener.onItemClick(getSnapshots().getSnapshot(position), position);
}
}
});
}
}
public interface OnItemClickListener {
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
}
But the dialog box always pop up indicating that the count is zero even though there is data inside of the recycler view. How can I fix this?
My guess is that the dialog you're talking about comes from here:
if(adapter.getItemCount() == 0){
dialog.show();
}
If so, it makes sense that it shows up as this code runs before any data has been loaded.
Data is loaded from Firestore (and most modern cloud APIs) asynchronously, and this changes the order in which code executes. It's easiest to see this if you set breakpoint on the if line above, on adapter.startListening(); and on the first line inside your onBindViewHolder.
If you now run the code in the debugger, you'll see that it:
First hits the if(adapter.getItemCount() == 0){ line
Then adapter.startListening()`
Then gets to onBindViewHolder
So now it hopefully makes sense why your code always show the dialog: no data has been loaded yet at that point.
The solution for this is always the same: you need to make sure that the code that needs the data runs after the data has been loaded. Since you're using the FirestoreRecyclerAdapter from FirebaseUI, you can do this inside its onDataChanged method that signals that a complete snapshot was loaded (regardless of whether there was any data in that snapshot) and is shown in the documentation on data and error events.
So if you move your if check into a onDataChanged method in your DobbyAdapter, it will get called whenever the adapter has loaded a complete snapshot, and it will show the dialog when there are no items.

Cardview Items in Recyclerview temporarily duplicating previous entries when adding new data

sing the dialogfragment to get the user input, while I am capable of updating the mainactivity using the ((MainActivity)getActivity()).storeDataInArrays(); command (This is in order to refresh the recyclerview to display the newly added contact).
However now there seems to be this new issue cropping up where only temporarily, instead of only showing the newly updated contact, it shows adds all of the previous contacts as well.Until I exit and enter the Mainactivity.
This is a demonstration of what's happening.
This is the Mainactivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
//widgets
public ImageButton eAddContact;
RecyclerView recyclerView;
DatabaseHelper myDB;
ArrayList<String> Contact_id, Contact_Name, Contact_Number;
CustomAdapter customAdapter;
Button btnEnterContact;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
eAddContact = findViewById(R.id.btnAddContact);
eAddContact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d(TAG, "onClick:opening dialog");
Dialog_AddContact dialog = new Dialog_AddContact();
dialog.show(getSupportFragmentManager(), "Add Contact Dialog");
}
});
//Toast.makeText(getApplicationContext(),"##",Toast.LENGTH_SHORT).show();
myDB = new DatabaseHelper(MainActivity.this);
Contact_id = new ArrayList<>();
Contact_Name = new ArrayList<>();
Contact_Number = new ArrayList<>();
recyclerView = findViewById(R.id.RecyclerView);
customAdapter = new CustomAdapter(MainActivity.this, Contact_id, Contact_Name, Contact_Number);
storeDataInArrays();
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
void storeDataInArrays() {
Cursor cursor = myDB.getEveryone();
if (cursor.getCount() == 0) {
//Add blank page
} else {
while (cursor.moveToNext()) {
Contact_id.add(cursor.getString(0));
Contact_Name.add(cursor.getString(1));
Contact_Number.add(cursor.getString(2));
}
}
customAdapter.notifyDataSetChanged();
}
}
and This is the dialogfragment's enter contact button where I call the Mainactivity fuction
btnEnterContact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ContactInfo ContactInfo;
try {
Log.d(TAG, "onClick: Entering Contact");
ContactInfo = new ContactInfo(-1,etName.getText().toString(),etPhonenumber.getText().toString());
Toast.makeText(getContext(),ContactInfo.toString(),Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(getContext(),"Error Creating Contact",Toast.LENGTH_SHORT).show();
ContactInfo = new ContactInfo(-1,"error","0");
}
DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
boolean success = databaseHelper.addOne(ContactInfo);
Toast.makeText(getContext(),"Success="+success,Toast.LENGTH_SHORT).show();
((MainActivity)getActivity()).storeDataInArrays();
getDialog().dismiss();
}
});
I would really appreciate any help in figuring out how to solve this.

How do I get the input of an activity into the recyclerview of another activity?

Updated Problem: My text of the SecondAcitivity is displayed in the recycling view of my MainActivity. However, the text in the Recyclerview will be overwritten.
How do I get it that the text in my recycling view is not overwritten, but is displayed in a further field one below the other?
I would like to have a button in my main activity that opens Activity 2. A text should then be entered there, which should then be displayed by clicking a button in the Recyclerview of the main activity.
I have already inserted a recylerview adapter, but the text is not output. Where is the problem?
On my XML i got 2 Buttons (one in the MainActivity (floatingActionButton) and one in the Second (sendNewTask))
My MainActivity:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
FloatingActionButton floatingActionButton;
TaskManager taskManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
taskManager = new TaskManager(this);
initViews();
initClickListener();
receiveIntent();
setRecyclerView();
}
protected void initViews(){
floatingActionButton = findViewById(R.id.floating_button);
recyclerView = findViewById(R.id.recyclerview);
}
protected void initClickListener(){
floatingActionButton.setOnClickListener(view -> onOpenButtonClicked());
}
protected void setRecyclerView(){
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new TaskListAdapter(taskManager));
recyclerView.getAdapter().notifyItemInserted(taskManager.getTaskListCount() - 1);
}
protected void onOpenButtonClicked(){
Intent i = new Intent(this, TaskActivity.class);
startActivity(i);
}
protected void receiveIntent(){
String inputTask = getIntent().getStringExtra("EXTRA_SESSION_TASK");
Task task = new Task();
task.setName(inputTask);
taskManager.addTask(task);
}
}
My SecondActivity:
public class TaskActivity extends AppCompatActivity {
EditText etAddTask;
ImageView sendNewTask;
TaskManager taskManager;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_task);
taskManager = new TaskManager(this);
initViews();
initClickListener();
}
protected void initViews(){
etAddTask = findViewById(R.id.et_new_task);
sendNewTask = findViewById(R.id.send_new_task);
}
protected void initClickListener(){
sendNewTask.setOnClickListener(view -> onSendButtonClicked());
}
protected void onSendButtonClicked(){
String newTaskName = etAddTask.getText().toString();
Task task = new Task();
task.setName(newTaskName);
taskManager.addTask(task);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
}
}
And my RecyclerAdapter & TaskViewHolder:
public class TaskListAdapter extends RecyclerView.Adapter<TaskViewHolder> {
TaskManager taskManager;
public TaskListAdapter(TaskManager taskManager){
this.taskManager = taskManager;
}
#NonNull
#Override
public TaskViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new TaskViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.task_row, parent, false));
}
#Override
public void onBindViewHolder(#NonNull TaskViewHolder holder, int position) {
Task task = taskManager.getTaskList().get(position);
holder.newTask.setText(task.getName());
}
#Override
public int getItemCount() {
return taskManager.getTaskListCount();
}
}
public class TaskViewHolder extends RecyclerView.ViewHolder {
TextView newTask;
public TaskViewHolder(#NonNull View itemView) {
super(itemView);
newTask = itemView.findViewById(R.id.tv_new_task);
}
}
TaskManager:
public class TaskManager {
ArrayList<Task> taskList = new ArrayList<>();
public TaskManager(Context context){
Hawk.init(context).build();
loadTaskList();
}
public void addTask(Task task){
taskList.add(task);
saveTaskList();
}
public void removeTask(Task task){
taskList.remove(task);
saveTaskList();
}
public ArrayList<Task> getTaskList(){
return taskList;
}
public int getTaskListCount(){
return taskList.size();
}
protected void saveTaskList(){
Hawk.put("taskList", taskList);
}
protected void loadTaskList(){
Hawk.get("taskList", new ArrayList<>());
}
}
Adding a task using a AlertDialog
If you don't need a whole new activity to just add a new task, you can use an AlertDialog.
public class MainActivity extends AppCompatActivity {
// ...
protected void onOpenButtonClicked(){
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Here you can set the View you want, even a LinearLayout. In this
// case, I'm adding a text field so user can type the task name
final EditText edittext = new EditText(this);
builder.setTitle("Enter the task name");
builder.setView(edittext);
alert.setPositiveButton("ADD", (dialog, which) -> {
// When the user clicks the add button of the dialog, here will
// be the task name the user has typed, so just add it to the
// task manager of this activity
final String newTaskName = edittext.getText().toString();
});
alert.setNegativeButton("CANCEL", (dialog, which) -> {
// When the user clicks the cancel button of the dialog, just
// dismiss it without doing any action
dialog.dismiss();
});
alert.create().show();
}
// ...
}
Keeping the previous tasks passing a StringArrayList
If you do need a new activity, you can keep the previous tasks by using a ArrayList and passing this around.
Requesting a new task:
public class MainActivity extends AppCompatActivity {
// ...
protected void onOpenButtonClicked(){
final Intent i = new Intent(this, TaskActivity.class);
// Transform the task list to a string list
final List<String> taskNames = taskManager.getTaskList().stream()
.map(task -> task.name).collect(Collesctions.toList());
// Put it into the intent and start a new activity
i.putStringArrayListExtra("TASK_NAME_LIST", new ArrayList<>(taskNames));
startActivity(i);
}
// ...
}
Fetching a new task name:
public class TaskActivity extends AppCompatActivity {
// ...
ArrayList<String> taskNames;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
// ...
final Intent i = getIntent();
// Receive the current task names
taskNames = getIntent().getStringArrayListExtra("TASK_NAME_LIST");
}
protected void onOpenButtonClicked() {
final String newTaskName = etAddTask.getText().toString();
// Add the new task name to the task names
taskNames.add(newTaskName);
// Send it back to the MainActivity
final Intent i = new Intent(this, MainActivity.class);
i.putStringArrayListExtra("TASK_NAME_LIST", taskNames);
startActivity(i);
finish();
}
// ...
}
Creating a new task:
public class MainActivity extends AppCompatActivity {
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
taskManager = new TaskManager(this);
final Intent i = getIntent();
if (i != null) {
// Receive the new task names
final List<String> taskNames = getIntent().getStringArrayListExtra("TASK_NAME_LIST");
for (String taskName : taskNames) {
final Task task = new Task();
task.setName(taskName);
taskManager.addTask(task);
}
}
}
// ...
}
NOTE: Even though in the previous example there are two separate MainActivity methods, you should include both.

Method used alongside OnCreate() to update an activity?

I have an android studio activity that contains a RecyclerView, Adapter, and an invisible button at the bottom of the activity. Each itemView thats inside the RecyclerView also has a CheckBox. Inside my Adapter Class I have my Checkbox initialized and has something like - if checkbox.isChecked - then make public static int num = 1 else num = 2; This static variable is then sent to my Activity_main where my bottom button that I need to become Visible can be visible using an if statement that says - if Adapter.num == 1 then button.MakeVisible(true);
Issue is that it's in my Oncreate which is only called once the activity is made. The static number is sent no problem but the activity doesn't update to actually show this. I have to restart the activity to have the button actually become visible.
Adapter Class
public static int p = 0;
#Override
public void onBindViewHolder(#NonNull final Adapter.CustomViewHolder holder,
final int position) {
addedCars = new ArrayList<>();
holder.car.setText(mCars.get(position).getCarName());
holder.mCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(holder.mCheckBox.isChecked()){
Log.d("tag1", "checked");
addedCars.add(mCars.get(position));
String x = Integer.toString(addedCars.size());
Log.d("tag1", x );
p = 1;
holder.mButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
else {
Log.d("tag1", "unchecked");
addedCars.remove(mCars.get(position));
p = 2;
}
}
});
}
Activity_Main Class
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
Button mButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.RecyclerView);
mButton = findViewById(R.id.button);
ArrayList<Car> cars = new ArrayList<>();
cars.add(new Car("Toyota"));
cars.add(new Car("Ford"));
cars.add(new Car("Tesla"));
mAdapter = new Adapter(cars);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setHasFixedSize(true);
if (mAdapter.p == 1){
mButton.setVisibility(View.VISIBLE);
}
}
}
If you want to send the num p from RecyclerView Adapter to the activity you need an interface to do so following steps to be followed :
have tested my code in android hope this works for you
creating an interface in the adapter
// create an instance of OnItemChangeListener
public OnItemChangeListener onItemChangeListener;
public interface OnItemChangeListener {
void onItemChanged(int p);
}
//set the instance of onItemChangeListener from the main activity
public void setOnItemChangeListener(OnItemChangeListener onItemChangeListener) {
this.onItemChangeListener = onItemChangeListener;
}
holder.mCheckBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(holder.mCheckBox.isChecked()){
Log.d("tag1", "checked");
addedCars.add(mCars.get(position));
String x = Integer.toString(addedCars.size());
Log.d("tag1", x );
p = 1;
/*
* notify updated value using call back
*/
onItemChangeListener.onItemChanged(p);
holder.mButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
}
2 finally notify update to the main activity
mAdapter = new Adapter(cars);
mAdapter.setOnItemChangeListener(new /*your adapter name */.OnItemChangeListener() {
#Override
public void onItemChanged(int p) {
// here you will get the latest updated value of p
// now you can update you view accordingly
}
});
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setHasFixedSize(true);

How to dynamically create buttons from Json string

I parsed JSON data from URL into a list and now I want to create buttons with every item of the list, but I can't figured out how to do this. I'm not sure if the list is the best idea, but I this was the solution I found online.
public class SecondActivity extends AppCompatActivity {
private String TAG = SecondActivity.class.getSimpleName();
private ProgressDialog pDialog;
private ListView lv;
private static String url = "https://ggysqqcz.p51.rt3.io/available-remotes/TV";
ArrayList<HashMap<String, String>> contactList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
contactList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(SecondActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray remotes = jsonObj.getJSONArray("remotes");
// looping through All Contacts
for (int i = 0; i < remotes.length(); i++) {
JSONObject c = remotes.getJSONObject(i);
String id = c.getString("id");
HashMap<String, String> contact = new HashMap<>();
contact.put("id", id);
contactList.add(contact);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
ListAdapter adapter = new SimpleAdapter(
SecondActivity.this, contactList,
R.layout.list_item, new String[]{"id"}, new int[]{button1});
lv.setAdapter(adapter);
}
}
public void onClickButton1(View view) {
startActivity(new Intent(getApplicationContext(), ThirdActivity.class));
}
}
This shows all the buttons, but obviously they all do the same thing when clicked because I have only button1. How can I make all the buttons do different activities?
I would like to suggest creating a custom adapter for your ListView which will have an onClick function for your button and based on the position of that item in your ListView, you can implement different actions in your onClick function. Hence I would like to suggest an adapter like the following.
public class ListAdapter extends ArrayAdapter<Item> {
private int resourceLayout;
private Context mContext;
private ArrayList<Contact> contacts;
public ListAdapter(Context context, int resource, ArrayList<Contact> contacts) {
super(context, resource, items);
this.resourceLayout = resource;
this.mContext = context;
this.contacts = contacts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(mContext);
v = vi.inflate(resourceLayout, null);
}
Item p = getItem(position);
if (p != null) {
Button btn = (TextView) v.findViewById(R.id.button1);
if (btn != null) {
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(position == 1) implementSomethingFor1();
else if (position == 2) implementSomethingFor2();
// ... Define the other implementations
}
});
}
}
return v;
}
}
And then use the adapter like the following.
ListView lv = (ListView) findViewById(R.id.list);
ListAdapter customAdapter = new ListAdapter(this, R.layout.list_item, contactList);
lv.setAdapter(customAdapter);
Please note that this is not an exact implementation. You should modify your custom adapter so that it serves your purpose.
try
lv.setonitemclicklisnter, this will create a method which will allow you to click on each and every item, you can write for example A Toast message inside this method so when you click on an item a Toast message will pop up.
You have several options:
Check the view parameter to determine what to do. You can use getTag() and setTag() to provide custom data on each button.
Create a custom adapter by extending SimpleAdapter. Override createView() and bindView() in order to provide custom behavior for each button, such as adding a different OnClickListener object to each button
Set the OnItemClickListener for the ListView. This provides a parameter for which position in the list view was clicked. You can use that to determine what to do or what data to pass to the new activity. You will likely want to use getItem() from your adapter to get the data for the current row.

Categories