I'm stuck for few days, and unfortunately dont know how to fix it.
I have DetailScreen.java that show data from MainScreen (one of recyclerview's list).
I tried this code but there is no effect, when i try to change use
COLUMN_NOMOR in my update function, i can change the name but
getting error when change the nomor. I guess, its right to use
COLUMN_ID in my update function because id is my PK-AI. So whether
because I didnt call COLUMN_ID in my DetailScreen? But how i can call my
id in my DetailsScreen also in my UpdateScreen?
If the data success updated, the screen will be automatically go to the DetailScreen again, but still showing old data. I had to go to MainActivity first to get the new data. Where code should i modified?
Here my Update function in my DBHandler.java
public int updateDataSiswa(Siswa siswa) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_NOMOR, siswa.getNomor());
values.put(COLUMN_NAMA, siswa.getNama());
return db.update(TABLE_SISWA, values, COLUMN_ID + " = ?",
new String[]{String.valueOf(siswa.getId())});
}
Here DetailScreen.java
public class DetailScreen extends AppCompatActivity {
private TextView txt_resultnomor, txt_resultnama;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen_details);
//put data
Intent i = getIntent();
final String id = i.getExtras().getString("id");
final String nomor = i.getExtras().getString("nomor");
final String nama = i.getExtras().getString("nama");
//inisialisasi
txt_resultnomor = (TextView) findViewById(R.id.txt_resultnomor);
txt_resultnama = (TextView) findViewById(R.id.txt_resultnama);
//set
txt_resultnomor.setText(nomor);
txt_resultnama.setText(nama);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_detail, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_edit) {
Intent in = new Intent(this, UpdateScreen.class);
in.putExtra("nomor", txt_resultnomor.getText().toString());
in.putExtra("nama", txt_resultnama.getText().toString());
startActivity(in);
}
if (id == R.id.action_delete) {
return true;
}
if (id == R.id.action_settings) {
// Intent i = new Intent(this, About.class);
//startActivity(i);
}
return super.onOptionsItemSelected(item);
}
}
Then here my UpdateScreen.java
public class UpdateScreen extends AppCompatActivity {
private EditText et_nomor;
private EditText et_nama;
private Button button_updatedata;
private DBHandler dbHandler;
private SiswaAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_screen);
dbHandler = new DBHandler(this);
initComponents();
}
private void initComponents(){
et_nomor = (EditText) findViewById(R.id.et_nomor);
et_nama = (EditText) findViewById(R.id.et_nama);
//ambil data
Intent in=getIntent();
final String id=in.getExtras().getString("id_siswa");
final String nomor=in.getExtras().getString("nomor");
final String nama=in.getExtras().getString("nama");
//set inisial
et_nomor.setText(nomor);
et_nama.setText(nama);
button_updatedata = (Button) findViewById(R.id.button_updatedata);
button_updatedata.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
validasiForm();
}
});
}
private void validasiForm() {
String form_nomor = et_nomor.getText().toString();
String form_nama = et_nama.getText().toString();
if (form_nomor.isEmpty()){
et_nomor.setError("Nomor belum diisi");
et_nomor.requestFocus();
}
else if (form_nama.isEmpty()){
et_nama.setError("Nama belum diisi");
et_nama.requestFocus();
}
else {
dbHandler.updateDataSiswa(new Siswa(form_nomor, form_nama));
List<Siswa> siswaList = dbHandler.getSemuaSiswa();
adapter = new SiswaAdapter(siswaList);
adapter.notifyDataSetChanged();
Toast.makeText(UpdateScreen.this, "Berhasil Memperbarui Data Siswa", Toast.LENGTH_SHORT).show();
MainSiswaActivity.mma.refresh();
finish();
}
}
}
I hope i tell clearly, help me please. Thanks.
where is your call to the update method you given public int updateDataSiswa(Siswa siswa)..? Also based on what you have provided...your notifyDataSetChanged() for adapter just tries to update the listview of the RecyclerView..
but it does not understand what underlying data has changed for it..you need to create a method for your Database Handler where you can fetch a List of new records..and then use this method to update your adapter with it and then set the new adapter to your listView in validasiForm() method..
please check this for more details...Android ListView not refreshing after notifyDataSetChanged
Related
I am fairly new in android programming.
I am having two cases where I am unable to get the list updated.
FIRST
Here is my Activity (QuestionList Activity).
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ques_list);
....
quesList=quesDB.getQues(); //getting arraylist from database
qAdapter = new QuesList_Adaptor(quesList, this, this);
rv_qlist.setAdapter(qAdapter);
qAdapter.notifyDataSetChanged();
}
On other activity, taking user input which updates the database (thus also updates quesList above).
public void save (View view)
{
String ques = et_ques.getText().toString();
String optionA = et_optA.getText().toString();
String optionB = et_optB.getText().toString();
String optionC = et_optC.getText().toString();
String optionD = et_optD.getText().toString();
String ans = et_ans.getText().toString();
QuesDB qd = new QuesDB(this);
boolean b = qd.addQues(ques, optionA, optionB, optionC, optionD, ans);
if (b)
{
Toast.makeText(this, "Question Saved", Toast.LENGTH_SHORT).show();
}
*//so... I have to notify adapter here right? than, what's the way here to reference adaptor and use notifyDataSetChanged*
finish();
SECOND CASE
Setting up Multi-delete on recyclerview. Data is getting deleted but trouble in refreshing the list.
Please take a look into the code, I mentioned there using comments.
On Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
..
StoreNotesDB sdb = new StoreNotesDB(this);
noteslist= sdb.getStoreNotes(); //storing from database to array
mAdapter = new AdaptorNotes(this,noteslist, this);
rv.setAdapter(mAdapter);
}
#Override
public void OnLongClick() {
fab.setVisibility(View.GONE);
inActionMode = true;
actionMode = this.startActionMode(new ContextualCallback());
mAdapter.notifyDataSetChanged();
}
#Override
public void OnClick(AdaptorNotes.MyViewHolder holder, int pos) {
if (holder.chk_notes.isChecked())
{
selected_list.add(noteslist.get(pos));
//counter = counter + 1;
}
else
{
selected_list.remove(noteslist.get(pos));
//counter = counter - 1;
}
}
class ContextualCallback implements ActionMode.Callback {
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
actionMode.getMenuInflater().inflate(R.menu.notescontextual_menu, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
//Toast.makeText(MainActivity.this,"delete",Toast.LENGTH_SHORT).show();
if (selected_list.isEmpty()) {
Toast.makeText(NotesListViewActivity.this, "No item is selected", Toast.LENGTH_SHORT).show();
}
else{
//loop for deleting item from database of the selected list
for (MyStoreNotes myStoreNotes: selected_list)
{
String x = String.valueOf(myStoreNotes.getSl());
int y = storeNotesDB.deleteRow(x);
}
mAdapter.notifyDataSetChanged(); // it doesn't work
inActionMode = false;
selected_list.clear();
Toast.makeText(NotesListViewActivity.this, "Selected List Deleted", Toast.LENGTH_SHORT).show();
actionMode.finish();
}
}
return false;
}......
.....
I'm not sure if you're trying to refresh the data on each load of the activity, or if you are using a different method to refresh your data.
If you want to reload the data each time the recyclerview activity is shown, then you need to call...
quesList.clear();
after declaring the list, and before getting the data. That ensures that you are populating your recyclerview with the latest data from your database.
If this is not what you're asking, please explain what your app is currently doing vs what you want it to do.
In my App I have stored some mockdata to show at the starting of the app. Now I have another option to add data into Realm database. But in my app, all the duplicate data is stored within the database. For Example I have three data in setRealmData() method. within this method I created same data with similar information. This data is checked perfectly. But whenever I tried to add a new data with simialer name it also stored within the app, which I do not want actually. How can I duplicate check in with preload data to new data in Realm.
My Activity Class is
public class MyColleaguesPage extends AppCompatActivity implements MyColleaguesAdapter.ColleagueListListener{
private RecyclerView recyclerView;
private MyColleaguesAdapter adapter;
private Realm colleagueRealm;
private RealmResults<MyColleagueModel> dataResult;
private static final String DIALOG_TAG = "EmployeeDialog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mycolleagues_layout);
// Showing and Enabling clicks on the Home/Up button
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
colleagueRealm = Realm.getDefaultInstance();
recyclerView = (RecyclerView) findViewById(R.id.colleagues_recycler);
setUpRecycler();
if (!Prefs.with(this).getPreLoad()) {
setRealmData();
}
showAllPersons();
}
private void showAllPersons() {
dataResult = colleagueRealm.where(MyColleagueModel.class).findAll();
setAdapter(dataResult);
adapter.notifyDataSetChanged();
}
private void setAdapter(RealmResults<MyColleagueModel> results) {
adapter = new MyColleaguesAdapter(this, colleagueRealm.where(MyColleagueModel.class).findAllSortedAsync("id"),this);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
private void setUpRecycler() {
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
recyclerView.setHasFixedSize(true);
// use a linear layout manager since the cards are vertically scrollable
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
}
private void setRealmData(){
List<MyColleagueModel> colleague = new ArrayList<>();
MyColleagueModel model = new MyColleagueModel();
model.setId(1);
model.setName("Name1");
model.setCompany("Comapny1");
model.setTitle("Title1");
colleague.add(model);
model = new MyColleagueModel();
model.setId(2);
model.setName("Name2");
model.setCompany("Comapny2");
model.setTitle("Title1");
colleague.add(model);
model = new MyColleagueModel();
model.setId(2);
model.setName("Name2");
model.setCompany("Comapny2");
model.setTitle("Title1");
colleague.add(model);
model = new MyColleagueModel();
model.setId(3);
model.setName("Name3");
model.setCompany("Comapny3");
model.setTitle("Title3");
colleague.add(model);
for (MyColleagueModel realmModel : colleague) {
// Persist the colleague data
colleagueRealm.beginTransaction();
colleagueRealm.copyToRealmOrUpdate(realmModel);
colleagueRealm.commitTransaction();
}
Prefs.with(this).setPreLoad(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.recycler_menu, menu);
final MenuItem item = menu.findItem(R.id.search);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
//onOptionsItemSelected(MenuItem item) add will open dialog box, which allows user to fill required data
if (id == R.id.addColleague) {
showAlertDialog();
return true;
}
return super.onOptionsItemSelected(item);
}
private void showAlertDialog() {
EditColleagueFragment dialog = new EditColleagueFragment();
//dialog.setPositiveButtonClickListener(this);
dialog.show(getSupportFragmentManager(), DIALOG_TAG);
//adapter.notifyDataSetChanged();
}
#Override
protected void onDestroy() {
if (colleagueRealm!= null)
colleagueRealm.close();
super.onDestroy();
}
}
My EditDialog Fragment Class is
public class EditColleagueFragment extends DialogFragment {
private EditText id;
private EditText name;
private EditText role;
private EditText company;
private EditText mobile;
private EditText email;
private EditText department;
private View view;
private LayoutInflater inflater;
private Realm mRealm;
/*public interface onSaveClickListener {
void onSaved();
}
private onSaveClickListener mSaveClickListener;
public void setPositiveButtonClickListener(onSaveClickListener listener){
mSaveClickListener=listener;
}*/
public EditColleagueFragment() {
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
inflater = getActivity().getLayoutInflater();
view = inflater.inflate(R.layout.edit_my_colleague, null);
id = (EditText) view.findViewById(R.id.id);
name = (EditText) view.findViewById(R.id.name);
role = (EditText) view.findViewById(R.id.role);
company = (EditText) view.findViewById(R.id.company);
mobile = (EditText) view.findViewById(R.id.mobile);
email = (EditText) view.findViewById(R.id.email);
department= (EditText) view.findViewById(R.id.department);
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
dialog.setTitle("Add Colleague");
dialog.setView(view);
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
dialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
savePerson();
}
});
return dialog.create();
}
private void savePerson() {
mRealm = Realm.getDefaultInstance();
mRealm.beginTransaction();
MyColleagueModel model=new MyColleagueModel();
model.setId(id.getId());
model.setName(name.getText().toString());
model.setTitle(role.getText().toString());
model.setCompany(company.getText().toString());
model.setMobile(mobile.getText().toString());
model.setEmail(email.getText().toString());
model.setDepartment(department.getText().toString());
mRealm.copyToRealmOrUpdate(model);
mRealm.commitTransaction();
mRealm.close();
}
}
The way to avoid duplication of data using the Realm Mobile Platform is to use primary keys.
Normally, all insertions and updates are preserved when synchronizing data between clients, but often multiple clients want to insert data that is logically identical. To ensure that those insertions are collapsed into single objects, you can use a primary key column on the model by which the objects can be identified on both clients. If two clients each insert an object with the same primary key value, the objects will be considered logically the same, and you will end up with just the one object after synchronization.
You haven't shared your model, but it looks like there is an "ID" field — that could serve as the primary key. :-)
Note that if you are only making local changes (no synchronization), primary key conflicts will result in an error being thrown, and you manually have to handle the case of preexisting objects.
If using primary keys is inconvenient for your use case, you always have the option to wait for download to complete and then manually clean up the database — just make sure that clients are able to make the same decisions about which object to discard, so as to avoid throwing away more than necessary.
try use code below
public <E extends RealmModel> boolean isDataExist(Class<E> eClass, int id) {
E data = colleagueRealm.where(eClass).equalTo("id", id).findFirst();
return data != null;
}
private void initData(){
if(isDataExist(MyColleagueModel.class, id.getText().toString())){
// data exist
}else{
// insert new
}
I have read many tutorial about CRUD SQLite, but most of them use Cursor to get values data and Button to call EditScreen. Any one lead me how to implementing i.putExtras in my Edit Menu Toolbar, please? I want to show again my data in EditText Form.
public class DetailStaffActivity extends AppCompatActivity {
private DBHandler dbHandler;
private TextView txt_resultnomor, txt_resultnama, txt_resulttempatlahir, txt_resulttanggallahir;
private List<Staff> staffList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.staff_details);
dbHandler = new DBHandler(this);
//ambil data
Intent i=getIntent();
final String nomor=i.getExtras().getString("nomor");
final String nama=i.getExtras().getString("nama");
final String tempatlahir = i.getExtras().getString("tempat_lahir");
final String tanggallahir=i.getExtras().getString("tanggal_lahir");
//inisialisasi dulu
txt_resultnomor = (TextView) findViewById(R.id.txt_resultnomor);
txt_resultnama = (TextView) findViewById(R.id.txt_resultnama);
txt_resulttempatlahir = (TextView) findViewById(R.id.txt_resulttempatlahir);
txt_resulttanggallahir = (TextView) findViewById(R.id.txt_resulttanggallahir);
//set inisial dengan data yang telah diambil di dengan intent
txt_resultnomor.setText(nomor);
txt_resultnama.setText(nama);
txt_resulttempatlahir.setText(tempatlahir);
txt_resulttanggallahir.setText(tanggallahir);
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_detail, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_edit) {
public void onItemClick(View view, int position) { //here, error when set position in this menu//
// TODO Handle item click
Intent in = new Intent(this, UpdateStaffActivity.class);
Staff staff = staffList.get(position);
String getNama = staffList.get(position).getNama();
in.putExtra("nama", getNama);
startActivity(in);
return true;
}
if (id == R.id.action_delete) {
return true;
}
if (id == R.id.action_settings) {
// Intent i = new Intent(this, About.class);
//startActivity(i);
}
return super.onOptionsItemSelected(item);
}
}
Please, how implementing putExtras in
if (id == R.id.action_edit) { }
I got error when set position in this menu. Thanks.
Just remove this line
public void onItemClick(View view, int position) { //here, error when set position in this menu//
// TODO Handle item click
Intent in = new Intent(this, UpdateStaffActivity.class);
Staff staff = staffList.get(position);
String getNama = staffList.get(position).getNama();
And write like this.
if (id == R.id.action_edit) {
Intent in = new Intent(this, UpdateMuriddActivity.class);
in.putExtra("nomor", txt_resultnomor.getText().toString());
in.putExtra("nama", txt_resultnama.getText().toString());
in.putExtra("tempat_lahir", txt_resulttempatlahir.getText().toString());
startActivity(in);
Hope its help.
I have a notebook sample project and I want to add a "note counter" to it using shared preferences and each time the user adds a note increment the counter in createNote() method. I also added a TextView to show the counter, but the counter is always zero and doesnt increment by creating a new note! ! Help me please!
public class MainActivity extends ListActivity {
private static final int EDITOR_ACTIVITY_REQUEST = 1001;
private static final int MENU_DELETE_ID = 1002;
private int currentNoteId;
private NotesDataSource datasource;
List<NoteItem> notesList;
int count = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
datasource = new NotesDataSource(this);
refreshDisplay();
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(""+count);
}
private void refreshDisplay() {
notesList = datasource.findAll();
ArrayAdapter<NoteItem> adapter =
new ArrayAdapter<NoteItem>(this, R.layout.list_item_layout, notesList);
setListAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_create) {
createNote(null);
}
return super.onOptionsItemSelected(item);
}
public void createNote(View v) {
NoteItem note = NoteItem.getNew();
Intent intent = new Intent(this, NoteEditorActivity.class);
intent.putExtra(NoteItem.KEY, note.getKey());
intent.putExtra(NoteItem.TEXT, note.getText());
startActivityForResult(intent, EDITOR_ACTIVITY_REQUEST);
int defaultValue = getPreferences(MODE_PRIVATE).getInt("count_key", count);
++defaultValue;
getPreferences(MODE_PRIVATE).edit().putInt("count_key", defaultValue).commit();
count = getPreferences(MODE_PRIVATE).getInt("count_key", count);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
NoteItem note = notesList.get(position);
Intent intent = new Intent(this, NoteEditorActivity.class);
intent.putExtra(NoteItem.KEY, note.getKey());
intent.putExtra(NoteItem.TEXT, note.getText());
startActivityForResult(intent, EDITOR_ACTIVITY_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == EDITOR_ACTIVITY_REQUEST && resultCode == RESULT_OK) {
NoteItem note = new NoteItem();
note.setKey(data.getStringExtra(NoteItem.KEY));
note.setText(data.getStringExtra(NoteItem.TEXT));
datasource.update(note);
refreshDisplay();
}
}
}
Your help is appreciated. Thanks!
Based on discussion and answer given by #Rahul Tiwari...do the following modifications in your code.....
First create the instance TextView variable
//your instance variables
int count;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
//your code...
tv = (TextView) findViewById(R.id.textView1);
count = getSharedPreferences("NAME_FOR_SHARED_PREFERENCES", Context.MODE_PRIVATE).getInt("count_key", 0);
updateTextView();
}
void updateTextView(){
tv.setText(""+count);
}
//your code till here....
public void createNote(View v) {
NoteItem note = NoteItem.getNew();
SharedPreferences sharedPref = getSharedPreferences("NAME_FOR_SHARED_PREFERENCES", Context.MODE_PRIVATE);
sharedPref.edit().putInt("count_key", ++count).commit();
updateTextView()
/*for intial testing commenting this code block
Intent intent = new Intent(this, NoteEditorActivity.class);
intent.putExtra(NoteItem.KEY, note.getKey());
intent.putExtra(NoteItem.TEXT, note.getText());
startActivityForResult(intent, EDITOR_ACTIVITY_REQUEST);
*/
}
//your code.
Then you can start app multiple times and check want is the count value.
Note: When naming your shared preference files, you should use a name
that's uniquely identifiable to your app, such as
"com.example.myapp.PREFERENCE_FILE_KEY" for more detail refer
your counter is not being refreshed as you are not changing text in your text view after changing the count.
you need to use
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(""+count);
at the end of your createNote function
use getDefaultSharedPreferences to access your shared preference across activities in your app. refer this answer for example.
I'm working on a simple log app that lets the user enter a time and a note, and then displays the entered data in a ListView in a dedicated activity (MainActivty). The time and data are entered in a separate activity (AddTimeActivity) with two EditText's and are passed to MainActivity when tapping the save button through an adapter (TimeTrackerAdapter). Alternatively, a cancel button can be pressed when the user changes their mind. The AddTimeActivity can be accessed through an add button in the action bar default menu. Now I've added a delete button -which is working fine- and an edit button to each row in the list. Now The problem is: How can I add the editing feature without making a new activity dedicated to editing. In Other words, how can I make the AddTimeActivity work with editing and adding in the same time, how can I make my app know that the user tapped the add button and start the AddTimeActivity with empty EditText's, or the user tapped the edit button in one of the rows in the list and passes the the data to be edited to AddTimeActivity and displays them in the EditText's and saves the edited data in the same entry? Sorry for not showing any attempts but I'm actually clueless about the issue.
MainActivity.java
public class MainActivity extends AppCompatActivity {
public TimeTrackerAdapter timeTrackerAdapter;
public int TIME_ENTRY_REQUEST_CODE = 1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.time_list);
timeTrackerAdapter = new TimeTrackerAdapter();
listView.setAdapter(timeTrackerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
super.onCreateOptionsMenu(menu);
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TIME_ENTRY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bundle bundle = data.getExtras();
String time = bundle.getString("time");
String note = bundle.getString("note");
TimeRecord timeRecord = new TimeRecord(time, note);
timeTrackerAdapter.addTimeRecord(timeRecord);
timeTrackerAdapter.notifyDataSetChanged();
}
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
// noinspection SimplifiableIfStatement
if (id == R.id.add_time_item) {
Intent intent = new Intent(getApplicationContext(), AddTimeActivity.class);
startActivityForResult(intent, TIME_ENTRY_REQUEST_CODE);
return true;
}
else if (id == R.id.about) {
Intent aboutIntent = new Intent(getApplicationContext(), AboutScreen.class);
startActivity(aboutIntent);
}
return super.onOptionsItemSelected(item);
}
}
The AddTimeActivity, onSave and onCancel are the buttons' methods:
public class AddTimeActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_time);
}
public void onCancel(View view) {
finish();
}
public void onSave(View view) {
Intent intent = new Intent(AddTimeActivity.this, MainActivity.class);
EditText timeEditText = (EditText) findViewById(R.id.Time_Edit_Text);
String time = timeEditText.getText().toString();
EditText noteEditText = (EditText) findViewById(R.id.Note_Edit_Text);
String note = noteEditText.getText().toString();
intent.putExtra("time", time);
intent.putExtra("note", note);
this.setResult(RESULT_OK, intent);
finish();
}
}
TimeTrackerAdapter.java:
public class TimeTrackerAdapter extends BaseAdapter {
public ArrayList<TimeRecord> times = new ArrayList<TimeRecord>();
#Override
public int getCount() {
return times.size();
}
public TimeTrackerAdapter() {
times.add(new TimeRecord("12:30", "this is the best"));
times.add(new TimeRecord("2:30", "I need this"));
}
#Override
public Object getItem(int position) {
return times.get(position);
}
public void addTimeRecord(TimeRecord timeRecord) {
times.add(timeRecord);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
if (view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.menu_layout, parent, false);
}
TextView timeView = (TextView) view.findViewById(R.id.time_textView);
TextView noteView = (TextView) view.findViewById(R.id.note_TextView);
Button deleteButton = (Button) view.findViewById(R.id.delete_entry);
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
times.remove(position);
notifyDataSetChanged();
}
});
TimeRecord time = times.get(position);
timeView.setText(time.getTime());
noteView.setText(time.getNote());
return view;
}
}
The question is
How can I add the editing feature without making a new activity dedicated to editing.
or, more generally,
"how do I hand over information to the activity I'm calling ?"
You achieve this by adding extras to the intent which you use to start the activity. For example, in your 'MainActivity' before calling 'startActivityForResult()':
Intent intent = new Intent(this, MyOtherActivity.class);
// in your case, 'extraInformation' could be a boolean (add = yes|no)
intent.putExtra("MyExtraInformationKey", extraInformation);
startActivityForResult(intent,TIME_ENTRY_REQUEST_CODE);
Then in the 'onCreate()' method of the other activity, you question the intent for extras:
Intent i = getIntent();
if (i != null && i.hasExtra(getString("MyExtraInformationKey"))
{
boolean myInfo = i.getBooleanExtra("MyExtraInformationKey");
// proceed as appropriate...
}
For your case of buttons inside ListView rows, you could make the OnClickListener method call another method (like 'doCallMayOtherActivity()') in your 'MainActivity', handing over all relevant information (like the position in the 'times' ArrayList).
This method would then start your add/edit activity, passing the old data out of 'times.get(position)' in a bundle as an extra to the intent.
To access the methods in 'MainActivity' from your adapter class, you could use the following code in 'getView()'
Button editButton=(Button) view.findViewById(R.id.edit_entry);
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)parent.getContext()).doCallMyOtherActivity(times.get(position));
}
This way, your other activity could check for the existence of that bundle. If there is none, you have a case of 'add'. Else, you have a case of 'edit'.