Refreshing TableLayout to show new rows inserted - android

Background:
I have created an Orders table in a database and I am manipulating it in two activities namely CurrentOrders and NewOrders respectively.
CurrentOrders activity shows the current orders stored inside the database in a TableLayout. And to add new orders to the table I have specified a button namely addOrders which when clicked loads NewOrders activity.
CurrentOrders:
public class CurrentOrders extends AppCompatActivity {
private TableLayout table;
populateTable(Cursor records){
TableRow row = new TableRow(this);
TextView product = new TextView(this);
TextView price = new TextView(this);
product.setText(records.getString(1));
price.setText(records.getString(2));
row.addView(product);
row.addView(price);
table.addView(row);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_current_orders);
Cursor cursor = db.query("orders", null, null,
null, null, null, null);
table = findViewById(R.id.tab);
while(cursor.moveToNext())
populateTable(cursor);
}
public void addOrders(View view){
startActivity(new Intent(getApplicationContext(), NewOrders.class));
}
}
NewOrders activity acts like a form by having a TableLayout whose cells/fields are specified as EditText in order to let user type the orders they want to store. And to save the orders inside the database I have specified a submit button which when clicked store the value of EditText inside the Orders table in database and then goes back to parent activity (CurrentOrders) to show all the orders in the database.
NewOrders:
public class NewOrders extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_orders);
}
public void submit(View view){
TableLayout table = findViewById(R.id.newOrders);
int count = table.getChildCount();
for (int idx = 0; idx < count; idx++){
TableRow row = (TableRow) table.getChildAt(idx);
EditText product = (EditText) row.getChildAt(1);
EditText price = (EditText) row.getChildAt(2);
String productVal = product.getText().toString();
double priceVal = Double.parseDouble(price.getText().toString());
long result = db.insert(productVal, priceVal);
}
Toast.makeText(this, "Saved.", Toast.LENGTH_SHORT).show();
onBackPressed();
}
}
Problem:
I don't see new records inserted until an unless I reload the CurrentOrders activity. I want to show all the records (included new ones) without having to reload the activity.

Finally created a simple solution:
First we need to modify our startActivity of CurrentOrder in such a way so that It receives data from NewOrders activity:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
// add newly added orders
if (data != null) {
String response = data.getStringExtra("newOrders");
if (requestCode == RequestCode && resultCode == RESULT_OK && !response.isEmpty()){
String[] orders = response.trim().split(" ");
for (String order : orders) {
// get new orders from the database
Cursor records = db.query("orders", null, "id = ?",
new String[] {String.valueOf(id)},
null, null, null);
records.moveToNext();
populateTable(records);
}
}
}
}
Then in addOrders method you need to replace startActivity with the following code:
startActivityForResult(new Intent(getApplicationContext(), NewOrders.class), 2);
Now coming to NewOrders activity here I have created a string variable that stores id's of the newly created orders:
public class NewOrders extends AppCompatActivity {
// created a string variable
private String newOrdersId = "";
// reset of the code
public void submit(View view){
// rest of the code
for (int idx = 0; idx < count; idx++){
// rest of the code
// record id's of orders inserted into the database
newOrderId += result + " ";
}
// reset of the code
}
}
And lastly you need to send the data to CurrentOrders by overriding onBackPressed method like this:
#Override
public void onBackPressed(){
Intent intent = getIntent();
intent.putExtra("newOrders", newOrdersId);
setResult(RESULT_OK, intent);
finish();
}

Related

Update Listview in first activity after returning from second activity

I have a List View in one activity with one info icon in custom adapter. When user taps on that info button then the next activity will open and after marking attendance in next activity when user taps the update button then the second activity should finish and first activity listview should be updated.
What i successfully did:
I have successfully mark the attendance and change the color of listview but i did that after closing the second activity and restarting the first activity. In this way the listview gets updated because of starting activity again.
What I am unable to do:
I want that when user taps on update button then only finish() will call and user returns to previous first activity with listview updated. But when i do so then the listview not get updated. I have to go back and open the activity again then the listview gets updated otherwise not. I do not want that. I also tried to notify adapter in the onResume method of first activity so that when user returns from second activity then the first activity listview adapter will be updated because of onResume method but it isn't work. Please Help
My Listview Activity Code:
public class TeacherWebserviceMainList extends Activity {
int attentedncemarkedCount = 0;
TextView addteacher;
DatabaseHandler databasehandler;
DetailsTeacherwebservice details;
String emis;
ArrayList<DetailsTeacherwebservice> addas = new ArrayList<DetailsTeacherwebservice>();
CustomAdapterTeacherWebservice cusadapter;
ArrayList<DetailsTeacherwebservice> teacherList;
private ListView listcontent = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.teacherwebservicemainlist );
addteacher = (TextView) findViewById(R.id.addteachermenu);
databasehandler = new DatabaseHandler(TeacherWebserviceMainList.this);
listcontent = (ListView) findViewById(R.id.teacher_list);
teacherList = databasehandler.teacherwebserviceList(emis);
Rsults();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if(resultCode == RESULT_OK) {
String update = data.getStringExtra("update");
if(update.equals("1"))
{
//cusadapter.
CustomAdapterTeacherWebservice adapter = new CustomAdapterTeacherWebservice(this, addas);
listcontent.setAdapter(adapter);
}
}
}
}
private void Rsults() {
addas.clear();
//DatabaseHandler databaseHandler=new DatabaseHandler(this);
//ArrayList<ArrayList<Object>> data = databaseHandler.abcTeacherNew();
for (int p = 0; p < teacherList.size(); p++) {
details = new DetailsTeacherwebservice();
//ArrayList<Object> baris = data.get(p);
details.setId(teacherList.get(p).getId());
details.setTeachername(teacherList.get(p).getTeachername());
details.setTeachercnic(teacherList.get(p).getTeachercnic());
details.setTeacherno(teacherList.get(p).getTeacherno());
details.setTeachergender(teacherList.get(p).getTeachergender());
details.setAttendance(teacherList.get(p).getAttendance());
details.setTeacherattendancedetails(teacherList.get(p).getTeacherattendancedetails());
details.setAttendancedatesince(teacherList.get(p).getAttendancedatesince());
details.setAttendancetrasnferschool(teacherList.get(p).getAttendancetrasnferschool());
addas.add(details);
}
cusadapter = new CustomAdapterTeacherWebservice(TeacherWebserviceMainList.this, addas);
listcontent.setAdapter(cusadapter);
listcontent.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
});
}
My List Adapter Code
public class CustomAdapterTeacherWebservice extends BaseAdapter {
private static ArrayList<DetailsTeacherwebservice> searchArrayList;
DatabaseHandler databaseHandler;
private Context context;
private LayoutInflater mInflater;
public CustomAdapterTeacherWebservice(Context context, ArrayList<DetailsTeacherwebservice> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
databaseHandler = new DatabaseHandler(context);
}
#Override
public int getCount() {
return searchArrayList.size();
}
#Override
public Object getItem(int p) {
return searchArrayList.get(p);
}
#Override
public long getItemId(int p) {
return p;
}
public int getViewTypeCount() {
return 500;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public View getView(final int p, View v, ViewGroup parent) {
ViewHolder holder;
context = parent.getContext();
if (v == null) {
v = mInflater
.inflate(R.layout.teacherwebserviceadapter, null);
holder = new ViewHolder();
holder.name = (TextView) v.findViewById(R.id.teacher_name);
holder.cnic = (TextView) v.findViewById(R.id.teacher_cnic);
holder.no = (TextView) v.findViewById(R.id.teacher_phone);
holder.gender = (TextView) v.findViewById(R.id.gender);
holder.status = (TextView) v.findViewById(R.id.status);
holder.info = (ImageView) v.findViewById(R.id.edit);
holder.l1 = (LinearLayout) v.findViewById(R.id.main);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.name.setText(searchArrayList.get(p).getTeachername());
holder.cnic.setText(searchArrayList.get(p).getTeachercnic());
holder.no.setText(searchArrayList.get(p).getTeacherno());
holder.gender.setText(searchArrayList.get(p).getTeachergender());
holder.status.setText(searchArrayList.get(p).getAttendance());
if (searchArrayList.get(p).getAttendance().equals("Absent"))
{
holder.l1.setBackgroundColor(Color.parseColor("#DB674D"));
}
if (searchArrayList.get(p).getAttendance().equals("Present"))
{
holder.l1.setBackgroundColor(Color.parseColor("#7EB674"));
}
if (searchArrayList.get(p).getAttendance().equals("Transfer Out"))
{
holder.l1.setBackgroundColor(Color.parseColor("#FBE87C"));
}
if (searchArrayList.get(p).getAttendance().equals("Resigned"))
{
holder.l1.setBackgroundColor(Color.parseColor("#4FC3F7"));
}
holder.info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent view_order_intent = new Intent(context, Teacherwebservicemainlistupdate.class);
view_order_intent.putExtra("ID", searchArrayList.get(p).getId());
view_order_intent.putExtra("tname", searchArrayList.get(p).getTeachername());
view_order_intent.putExtra("tgender", searchArrayList.get(p).getTeachergender());
view_order_intent.putExtra("tcnic", searchArrayList.get(p).getTeachercnic());
view_order_intent.putExtra("tno", searchArrayList.get(p).getTeacherno());
view_order_intent.putExtra("tatt", searchArrayList.get(p).getAttendance());
view_order_intent.putExtra("tattdetails", searchArrayList.get(p).getTeacherattendancedetails());
view_order_intent.putExtra("tattdatesince", searchArrayList.get(p).getAttendancedatesince());
view_order_intent.putExtra("tatttrasnferout", searchArrayList.get(p).getAttendancetrasnferschool());
//context.startActivity(view_order_intent);
((Activity)context).startActivityForResult(view_order_intent, 1);
}
});
return v;
}
static class ViewHolder {
TextView name, cnic, no, gender,status;
ImageView info;
LinearLayout l1;
}
here in adapter code when INFO button is clicked then another activity starts in which user can update the attendance.
This is Update activity code when button clicked:
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DetailsTeacherwebservice schoolinfo = new DetailsTeacherwebservice();
schoolinfo.setTeachername(teachername.getText().toString());
schoolinfo.setTeacherno(teacherno.getText().toString());
schoolinfo.setTeachercnic(teachercnic.getText().toString());
schoolinfo.setTeachergender(teachergender.getText().toString());
schoolinfo.setAttendance(teachergroupstr);
schoolinfo.setTeacherattendancedetails(absentgrpstr);
schoolinfo.setAttendancedatesince(txtDate.getText().toString());
schoolinfo.setAttendancetrasnferschool(transferOutSchool.getText().toString());
databasehandler.updateteacherwebservice(schoolinfo, emis, identity);
Toast.makeText(Teacherwebservicemainlistupdate.this, "Updated Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("update", "1");
setResult(RESULT_OK, intent);
finish();
}
}
});
I can start the listview activity again when update button is clicked but that changes the index of the list item clicked i.e. because activity starts again. How ever what i want is that if i clicked on 10th item then when next activity opens and user updates attendance then it returns back to previous activity on same index position so that the user do not have to scroll again to go back on 10th item
Add this code for list item click:
Intent i = new Intent(context, YourAcitivityName.class);
i.putExtra("position",p);
startActivityForResult(i, 1);
Add this code in update button:
Intent intent = new Intent();
intent.putExtra("update", "1");
intent.putExtra("position",getIntent().getIntExtra("position",0));
setResult(RESULT_OK, intent);
finish();
When you get back from activity to the activity where list view is implemented this method called:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if(resultCode == RESULT_OK) {
String update = data.getStringExtra("update");
if(update.equals("1"))
{
// add your code to update list view
teacherList = databasehandler.teacherwebserviceList(emis);
Rsults();
YourAdapterClassName adapter = new YourAdapterClassName(this, arrList);
listView.setAdapter(adapter);
listView.smoothScrollToPosition(getIntent().getIntExtra("position",0));
}
}
}
}
The following are two examples, the first is an example where the source for the ListView is a List (and in this case using a Custom Adapter), the second is where the source is a Cursor (using SimpleCursorAdapter)
The trap many fall into is just updating the List using something like :-
myList = method();
myAdapter.notifyDataSetChanged();
At a guess, that's the trap you've fallen into.
When what should be done is to use the List's methods to alter it (e.g. clear, add, addAll, remove).
I believe this explains the reasoning - Is Java “pass-by-reference” or “pass-by-value”?
Example 1 - List as the source :-
/**
* Build or rebuild the List of TaskData's, instantiate the
* Custom Array Adapter if needed and also notify the adapter
* if the List may have been changed.
*/
private void prepTasksCustomArrayList() {
// Determine if the adpater needs to be notified of changes
boolean notify_dataset_changed = (mCsr != null && mCustomArrayAdapter != null);
// If the List is not null then assume that it has changed
// otherwise just get the List
if (mTasks != null) {
mTasks.clear();
mTasks.addAll(dbhlpr.getAllTasks());
} else {
mTasks = dbhlpr.getAllTasks();
}
// If the adapter is null then instantiate it
if (mCustomArrayAdapter == null) {
mCustomArrayAdapter = new CustomArrayAdapter(
this,
R.layout.taskdata_item,
mTasks);
}
// Notify the adapter that the List has changed
if (notify_dataset_changed) {
mCustomArrayAdapter.notifyDataSetChanged();
}
}
Notes
This is used to both setup and alter/update the ListView that the adpater is attached to.
All that is needed is to call the method at the appropriate place/s in the code e.g. in the Activities onCreate, onResume, after onItemClick/LongClick.
e.g in onCreate :-
mTaskList = this.findViewById(R.id.tasklist); // The ListView
prepTasksCustomArrayList()
mTaskList.setAdapter(mCustomArrayAdapter)
and in onresume just (in conjunction with the 3 lines in onCreate)
prepTasksCustomArrayList()
I don't believe that this way is very common, normally you see the adapter being setup in onCreate.
mTasks.addAll(dbhlpr.getAllTasks()); is what gets the source data.
Example 2 - Cursor as the Source
/**
* Build or rebuild the List via Cursor using the bespoke layout
*/
private void prepCursorListBespoke() {
boolean swapcursor = (mCsr != null && mCursorAdapter2 != null);
if (mCursorAdapter2 == null) {
mCursorAdapter2 = new SimpleCursorAdapter(this,R.layout.taskdata_item,mCsr,
new String[]{ Datasource.TASKS_ID_COL,
Datasource.TASKS_TYPE_COL,
Datasource.TASKS_NAME_COL,
Datasource.TASKS_OWNER_COL,
Datasource.TASKS_EXPIRATION_COL},
new int[]{R.id.task_id,
R.id.task_type,
R.id.task_name,
R.id.task_owner,
R.id.task_expiration},
0);
}
if (swapcursor) {
mCursorAdapter2.swapCursor(mCsr);
}
}
Notes
The prepCursorListBespoke method is used in the same way as for example 1.
notifyDataSetChanged could be used instead of swapCursor
I use swapCursor because it's more descriptive).
However, you can only use swapCursor for Cursors.
Added
The following changes may work, roughly speaking I've applied the List example above.
i.e. Rsults is called by onResume(added) which will notify the adapter that the data has been changed.
The code hasn't been tested as there was insufficient code. (a no code for DatabaseHandler class, and b) no code for DetailsTeacherwebservice class). As such there may be errors.
Look for //++++++++++++++... comments should follow to say what has been done/changed.
public class MainActivity extends Activity {
int attentedncemarkedCount = 0;
TextView addteacher;
DatabaseHandler databasehandler;
DetailsTeacherwebservice details;
String emis;
ArrayList<DetailsTeacherwebservice> addas = new ArrayList<DetailsTeacherwebservice>();
CustomAdapterTeacherWebservice cusadapter;
ArrayList<DetailsTeacherwebservice> teacherList;
private ListView listcontent = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.teacherwebservicemainlist);
addteacher = (TextView) findViewById(R.id.addteachermenu);
databasehandler = new DatabaseHandler(TeacherWebserviceMainList.this);
listcontent = (ListView) findViewById(R.id.teacher_list);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//MOVED On ItemClickListener block FROM Rsults to here.
listcontent.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
});
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
teacherList = databasehandler.teacherwebserviceList(emis);
Rsults();
}
// Probably don't even need onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
String update = data.getStringExtra("update");
if (update.equals("1")) {
//cusadapter.
//CustomAdapterTeacherWebservice adapter = new CustomAdapterTeacherWebservice(this, addas);
//+++++++++++++++++++++++++++++++++++
// Commented out
//listcontent.setAdapter(adapter);
}
}
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Added onResume to call Rsults
#Override
public void onResume() {
super.onResume();
Rsults();
}
private void Rsults() {
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ADDED 4 lines to see if the notifyDataSetChanged is required
boolean notifydschg_needed = false;
if (cusadapter != null) {
notifydschg_needed = true;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// YOU NEED TO GET THE TEACHER LIST AGAIN AS THE DB HAS CHANGED
teacherList = databasehandler.teacherwebserviceList(emis);
addas.clear();
//DatabaseHandler databaseHandler=new DatabaseHandler(this);
//ArrayList<ArrayList<Object>> data = databaseHandler.abcTeacherNew();
for (int p = 0; p < teacherList.size(); p++) {
details = new DetailsTeacherwebservice();
//ArrayList<Object> baris = data.get(p);
details.setId(teacherList.get(p).getId());
details.setTeachername(teacherList.get(p).getTeachername());
details.setTeachercnic(teacherList.get(p).getTeachercnic());
details.setTeacherno(teacherList.get(p).getTeacherno());
details.setTeachergender(teacherList.get(p).getTeachergender());
details.setAttendance(teacherList.get(p).getAttendance());
details.setTeacherattendancedetails(teacherList.get(p).getTeacherattendancedetails());
details.setAttendancedatesince(teacherList.get(p).getAttendancedatesince());
details.setAttendancetrasnferschool(teacherList.get(p).getAttendancetrasnferschool());
addas.add(details);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Just create the adapter and attach it to the listview once
if (cusadapter == null) {
cusadapter = new CustomAdapterTeacherWebservice(TeacherWebserviceMainList.this, addas);
listcontent.setAdapter(cusadapter);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Notify the adapter that the data has been changed
if(notifydschg_needed) {
cusadapter.notifyDataSetChanged();
}
}
}
// you have to set data in adapter in onResume method
#Override
protected void onResume() {
super.onResume();
}
You can use eventbus for this case:
This is an example:
In your build.gradle file
compile 'org.greenrobot:eventbus:3.0.0'
In Activity has listview:
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this); // register event
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this); // unregister event
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(EventBusInfo eventBusInfo) {
if (eventBusInfo.getProcessId() == 99) {
// eventBusInfo.getData();
notifyDataSetChanged();
}
}
In Update Activity
yourButtonFinish.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
EventBusInfo event = new EventBusInfo();
event.setProcessId(99);
//event.setData(object) //if you want get data back
EventBus.getDefault().post(event);
}
});
Class EventBusInfo
public class EventBusInfo {
private int processId;
private Object data;
public EventBusInfo(int processId, Object data) {
this.processId = processId;
this.data = data;
}
public EventBusInfo() {
}
public EventBusInfo(int processId) {
this.processId = processId;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public int getProcessId() {
return processId;
}
public void setProcessId(int processId) {
this.processId = processId;
}
}
save the list items in every change then restart the Activity of adapter with intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) to close the old ListView.
Is what I do and it works fine.
if the list it is not empty, I restart the activity with the adapter and I have a new ListView closing the previous one. Or if it is empty, I start a different activity (to not have an empty ListView)
Saving and loading the list items every time to SharedPreferences with Gson
For a reason notifyDataSetChanged() does not work good in my case so I prefer this solution.

How to access a TextView located in a Table Layout

I made a TableLayout 3x3 in "Activity A"(Chose a Table Layout, because I thought it suits my needs)
7 of the 9 cells are clickable and open "Activity B" which is a custom number picker I made.
I used an intent to pass an array and other data to activiy B
The idea of my number picker is to set a value in the cell I just clicked in Activiy A(I wanted something like the calendarDatePicker)
In "Activity B" I have a method to update the values from "Activity A" and finish() "Activity B" when an image View is clicked wich works very fine except that it does not set the value for the clicked Text View
How can I set the TextValue from another activity when the TextValue is contained in a Table Layout?
I don't use intent, because honestly I don't know how to handle it when the "Activity B" is closed.
I mean where in "Activity A" should I handle this intent from "Activity B"
Using the debugger I found out that trying to set the text using the TextView Id does not works as it shows a "null" object in the debugger.
Activiy A
package com.example.racu.threebythree;
public class threebythree extends AppCompatActivity {
public static ArrayList<Integer> ColumnA = new ArrayList<Integer>();
public static ArrayList<Integer> ColumnB = new ArrayList<Integer>();
public static ArrayList<Integer> ColumnC = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_three_by_three);
for (int i = 1; i < 28; i++) {
if (i > 0 && i < 10)
ColumnA.add(i);
if (i > 10 && i < 19)
ColumnB.add(i);
if (i > 19 && i < 28)
ColumnC.add(i);
}
}
public void openNumberPicker(View v) {
// I used this to "guess" the location of the cell in the table layout as I could not find a way to do it.
String cellName = v.getResources().getResourceName(v.getId());
String cellLetter = cellName.substring(cellName.lastIndexOf("/") + 1);
// Send intent
Intent intent = new Intent(this, NumberPicker.class);
intent.putExtra("Id", (cellLetter.substring(0, 1) + cellLetter.substring(2)).toUpperCase());
switch (cellLetter.substring(0, 1)) {
case ("a"):
intent.putIntegerArrayListExtra("Column", ColumnA);
break;
case ("b"):
intent.putIntegerArrayListExtra("Column", ColumnB);
break;
case ("c"):
intent.putIntegerArrayListExtra("Column", ColumnC);
break;
}
intent.putExtra("Cell ID", v.getId());
startActivity(intent);
}
}
Avtivity B
package com.example.racu.threebythree;
public class NumberPicker extends AppCompatActivity {
GridView numberPicker;
ArrayList<Integer> numbersToDisplay;
TextView viewToDisplay;
ImageView ok, cancel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_number_picker);
numberPicker = (GridView) findViewById(R.id.arrayNumbers);
viewToDisplay = (TextView) findViewById(R.id.number_to_select);
ok = (ImageView) findViewById(R.id.add_number_to_card);
ok.setClickable(false);
Intent intent = getIntent();
String idFromIntent = intent.getStringExtra("Id");
numbersToDisplay = intent.getIntegerArrayListExtra("Letter");
TextView numberPosition = (TextView) findViewById(R.id.numberPosition);
numberPosition.setText(idFromIntent);
final TextView chosenNumber = (TextView) findViewById(R.id.chosenNumber);
ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, R.layout.number_for_picker, numbersToDisplay);
numberPicker.setAdapter(adapter);
numberPicker.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
chosenNumber.setText(((TextView) v).getText());
ok.setImageResource(R.drawable.ok_blue);
ok.setClickable(true);
}
});
}
public void updateThreByThree(View v) {
Intent intent = getIntent();
int currentCell = intent.getIntExtra("Cell ID", 0);
String idFromIntent = intent.getStringExtra("Id").substring(0, 1);
TextView chosenNumber = (TextView) findViewById(R.id.chosenNumber);
// Here I try to Set the text to the cell in Activity A, using its R.id, but in the debugger I get a null reference, therefore my app crashes
TextView currentCellToEdit = (TextView) findViewById(currentCell);
currentCellToEdit.setText(chosenNumber.getText());
int temp = Integer.parseInt(chosenNumber.getText().toString());
switch (idFromIntent) {
case "A":
threebythree.ColumnA.remove(Integer.valueOf(temp));
break;
case "B":
threebythree.ColumnB.remove(Integer.valueOf(temp));
break;
case "C":
threebythree.ColumnC.remove(Integer.valueOf(temp));
break;
}
finish();
}
public void cancel(View view) {
finish();
}
}
Thanks to Pavan for the hint I found two more very helpful post here and this one was EXACTLY what I was looking for.
Like that ( make sure you give the TableLayout an id ):
TableLayout tl = (TableLayout)findViewById( R.id.tableLayout );
TextView tv = (TextView)tl.findViewById( R.id.textView );

How to reach variables in an activity file from another activity file?

i have two activity files in my code, and the first activity file loads the layout search, and the second file loads layout list. I have a textbox in layout search and enter some text. I want to use this text in my second activity file but i can not reach it since it is in the layout search. How can i do this? Here the first activity file, here there is an EditText item called searchedText, and i want to use it in the second activity file.
public class SearchActivity extends Activity{
public EditText searchedText;
public RadioGroup radioGroup;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
}
public void onStart(){
super.onStart();
searchedText = (EditText) findViewById(R.id.searchText);
Button searchinSearchButton = (Button)findViewById(R.id.searchInSearch);
radioGroup = (RadioGroup) findViewById(R.id.radioGroup1);
searchinSearchButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
String searched=searchedText.getText().toString();
Intent myIntent = new Intent(v.getContext(),
SearchListActivity.class);
startActivityForResult(myIntent, 1);
}
});
}
}
And here is the second activity file:
public class SearchListActivity extends Activity{
public DatabaseAdapter db;
public ArrayList<String> myList;
public ListView listview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
db = new DatabaseAdapter(this);
myList = new ArrayList<String>();
getContacts();
// Example of retrieving tweets of the user "mashable" and adding them to
myList
/*
ArrayList<Tweet> tweets= new ArrayList<Tweet>();
tweets.addAll(Twitter.getTimeline("mashable", 10));
for(Tweet t: tweets){
myList.add(t.username + ": " + t.message + " Tweet id: "+ t.id);
}
*/
printList();
}
public void printList(){
listview = (ListView)findViewById(R.id.contactcListView);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, myList);
listview.setAdapter(adapter);
}
public void getContacts() {
db.open();
Cursor c = db.getContactbyName("y");
if (c.moveToFirst()) {
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
}
public void DisplayContact(Cursor c) {
String entry = "";
// if you add another attribute to your table, you need to change 3 into x
for (int i=1; i<5;i++){
entry += c.getString(i) + "\n";
}
myList.add(entry);
}
}
In this second activity file, you can see the getContacts() method. There, i search by Cursor c = db.getContactbyName("y"); but instead of "y", i want to search whatever user enters the texbox, whic is in the 1st activity file called searchedText. How can i do this?
Thanks
Send the text as an extra in your Intent when you start your second activity.
searchinSearchButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
String searched=searchedText.getText().toString();
Intent myIntent = new Intent(v.getContext(),
SearchListActivity.class);
myIntent.putExtra("SEARCH_STRING",searched);
startActivityForResult(myIntent, 1);
}
});
And in your onCreate get the extra. You could use Intent.getStringExtra(String name)
In other words:
mySearched = getIntent().getStringExtra("SEARCH_STRING");
Just make sure to see if anything is null before using it.

Generate TextViews with loop and enable click for each one

i'm making an Android App and in my activity that follows i execute a query to the database and i take the results. I take the results and make TextViews to the Activity. I want when i click the TextView, to pass to the next Activity the name of the Restaurant i click. The problem with my code is that for all the TextViews it save the name of the last Restaurant. Any ideas? Thank you!
public class ViewRestaurants extends Activity{
String name;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.row_restaurant);
DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getSpRestaurants(getIntent().getStringExtra("city"), getIntent().getStringExtra("area"), getIntent().getStringExtra("cuisine"));
View layout = findViewById(R.id.items);
if(c.moveToFirst())
{
do{
name = c.getString(0);
TextView resname = new TextView(this);
TextView res = new TextView(this);
View line = new View(this);
resname.setText(c.getString(0));
resname.setTextColor(Color.RED);
resname.setTextSize(30);
resname.setTypeface(null,Typeface.BOLD);
res.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
res.setText(c.getString(1)+","+c.getString(2)+","+c.getString(3)+"\n"+c.getString(4));
res.setTextSize(20);
res.setTextColor(Color.WHITE);
res.setClickable(true);
res.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent();
i.setClassName("com.mdl.cyrestaurants.guide", "com.mdl.cyrestaurants.guide.RestaurantDetails");
i.putExtra("name",name);
startActivity(i);
}
});
line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,2));
line.setBackgroundColor(Color.RED);
((LinearLayout) layout).addView(resname);
((LinearLayout) layout).addView(res);
((LinearLayout) layout).addView(line);
}while (c.moveToNext());
}
db.close();
}
}
You'll need to make your name final within your loop and remove it as a class field in order to use it in the OnClickListener the way you are.
if(c.moveToFirst())
{
do{
final String name = c.getString(0);
//other code ...
res.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent();
i.setClassName("com.mdl.cyrestaurants.guide", "com.mdl.cyrestaurants.guide.RestaurantDetails");
i.putExtra("name",name);
startActivity(i);
}
});
//more code...
}while (c.moveToNext());
}
Try making these changes
String name = c.getString(0);
resname.setText(name);
The reason why it is setting to the last restaurant name is because string is being passed by reference rather than by value as it is an object. Creating a unique string within the scope of the do while loop should solve this.

Refresh ListView with ArrayAdapter after editing an Item

I have a ListView, which displays a list of notes taken from a table in SQLiteDatabase with ArrayAdapter.
public class NotepadActivity extends ListActivity {
protected static final int ADD_NEW_NOTE = 0;
protected static final int EDIT_NOTE = 1;
ArrayAdapter<Note> adapter;
NotesManager manager;
private Note nNoteToDelete;
ArrayList<Note> lstAllNotes;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findViewById(R.id.btnAddNewNote).setOnClickListener(addNewNote);
manager = new NotesManager(this);
lstAllNotes = manager.getAllNotes();
adapter = new ArrayAdapter<Note>(this, R.layout.note, lstAllNotes);
setListAdapter(adapter);
getListView().setOnItemClickListener(editNote);
registerForContextMenu(getListView());
}
When I click on an Item in this ListView, it takes this Note object to the EditNote activity:
private OnItemClickListener editNote = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Note currNote = (Note)parent.getItemAtPosition(position);
int curr_note_id = currNote.getId();
String curr_note_title = currNote.getTitle().toString();
String curr_note_details = currNote.getDetails().toString();
Intent editNote = new Intent(NotepadActivity.this, EditNote.class);
editNote.putExtra("CURR_NOTE_ID", curr_note_id);
editNote.putExtra("CURR_NOTE_TITLE", curr_note_title);
editNote.putExtra("CURR_NOTE_DETAILS", curr_note_details);
startActivityForResult(editNote, EDIT_NOTE);
}
};
I can edit the title of the note in there and the content. When I hit the Save button, it sends back to the main activity the Strings of Title and the Details and the ID int:
public class EditNote extends Activity implements OnClickListener {
int curr_note_id;
String curr_note_title;
String curr_note_details;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editnote);
curr_note_id = getIntent().getExtras().getInt("CURR_NOTE_ID");
curr_note_title = getIntent().getExtras().getString("CURR_NOTE_TITLE");
curr_note_details = getIntent().getExtras().getString(
"CURR_NOTE_DETAILS");
((EditText) findViewById(R.id.edtTitle)).setText(curr_note_title);
((EditText) findViewById(R.id.edtDetails)).setText(curr_note_details);
findViewById(R.id.btnSave).setOnClickListener(this);
findViewById(R.id.btnCancel).setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnSave:
String strNoteTitle = ((EditText) findViewById(R.id.edtTitle)).getText().toString().trim();
String strNoteDetails = ((EditText) findViewById(R.id.edtDetails)).getText().toString().trim();
if (!strNoteTitle.equals("")) {
Intent data = new Intent();
data.putExtra("NOTE_ID", curr_note_id);
data.putExtra("NOTE_TITLE", strNoteTitle);
data.putExtra("NOTE_DETAILS", strNoteDetails);
setResult(RESULT_OK, data);
finish();
} else {
((EditText) findViewById(R.id.edtTitle))
.setError("A note must contain a title");
}
break;
case R.id.btnCancel:
setResult(RESULT_CANCELED);
finish();
break;
}
}
}
And in the main activity it should update the DB and the ListView with the new Title, if there were changes. My code does update the DB, but I don't see the change in the ListView immediately, only if I exit the app and open it again. Here's the code (watch the second case, EDIT_NOTE):
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case ADD_NEW_NOTE:
String noteTitle = data.getExtras().getString("NOTE_TITLE");
String noteDetails = data.getExtras().getString("NOTE_DETAILS");
Note nNewNote = new Note(-1, noteTitle, noteDetails);
adapter.add(nNewNote);
manager.addNote(nNewNote);
break;
case EDIT_NOTE:
int noteID = data.getExtras().getInt("NOTE_ID");
noteTitle = data.getExtras().getString("NOTE_TITLE");
noteDetails = data.getExtras().getString("NOTE_DETAILS");
nNewNote = new Note(noteID, noteTitle, noteDetails);
Toast.makeText(NotepadActivity.this, noteTitle + "\n" + noteDetails, Toast.LENGTH_SHORT).show();
manager.updateNote(nNewNote);
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
After manager.updateNote(nNewNote); I tried to use adapter.notifyDataSetChanged(); but that didn't work - I didn't see the change in the ListView. Perhaps I used it wrong, perhaps I should use something else...
So how can I make the ListView refresh? How can I see change immediately, without restarting the app?
Thank you!
When you return from the edit activity, set the list adapter again to refresh the ListView. You have to manually refresh the ListView each time if you want to see any updates. Hope this helps.

Categories

Resources