I have created two Activities.
Main Activity.java(This is the activity that application launches with, user click on a button called "Show timer" which takes the user to the next activity)
displayTimer.java(This is the second activity which has a ListView, with data in each row. on item click users comes back to the main activity)
I'm trying to pass the string stored in that row to the main activity.
This is the main code from display timer activity
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_list_view);
listView = (ListView) findViewById(R.id.customtimer_listview);
customTimerAdapter = new CustomTimerAdapter(this, R.layout.row);
BackGroundTask backGroundTask = new BackGroundTask(this);
backGroundTask.execute("Get_info");
registerForContextMenu(listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(R.id.time_entered);
String timeRetrevied = textView.getText().toString();
//System.out.println(timeRetrevied);
Intent intentExtras = new Intent(displayTimer.this,MainActivity.class);
intentExtras.putExtra("TIME_DATA",timeRetrevied);
setResult(RESULT_OK, intentExtras);
//startActivityForResult(intentExtras,SECOND_ACTIVITY_REQUEST_CODE,null);
finish();
}
});
}
This is the code from the Main activity where i'm calling the method onActivityResult to get the data through intent from displaytimer. But i'm not able to get the data. Dont know what i'm doing wrong. Any input with be fine.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SECOND_ACTIVITY_REQUEST_CODE){
if (resultCode == RESULT_OK) {
int setTimer = Integer.parseInt(data.getDataString());
System.out.println(setTimer);
seekbar.setProgress(setTimer * 60);
updateTimer(setTimer);
}
else{
System.out.println("Not Ok");
}
}
System.out.println("RequestCode failed");
}
}
Instead of
data.getDataString()
use
data.getStringExtra("TIME_DATA")
getDataString returns the URI in the encoded String format, which is not what you require as you are not passing in the data.
As you are passing in the Sting text with ID=TIME_DATA, use the same ID to get the string back using the getStringExtra("TIME_DATA");
Related
I am trying to implement RecyclerView in a small project and ran into some problem. My adapter works fine for adding new elements, but doesn't do anything when I edit existing ones.
For creating a new element I use FloatingActionButton in my fragment and send an appropiate request code. For editing an element I tried implementing onClickListener() in onBindViewHolder(). Here's the code:
#Override
public void onBindViewHolder(RecyclerViewAdapter.EventViewHolder holder, int position) {
final Event event = mEvents.get(position);
holder.mLabel.setText(event.getLabel());
holder.mComment.setText(event.getComment());
holder.mStartTime.setText(DateFormat.format("HH:mm", event.getTime()));
holder.mDuration.setText(event.getDurationInFormat(mContext));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext.getApplicationContext(), EventCreatorActivity.class);
intent.putExtra(EX_EVENT_ID, event.getId());
intent.putExtra(EX_DAY_ID, event.getParent().getId());
((Activity) mContext).startActivityForResult(intent, DayViewFragment.RC_EDIT);
}
});
}
(itemView is where I keep the entire element view, and the Textviews are just components).
Here's where I initialize the RecyclerViewAdapter:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Restore data after app-configuration
if(savedInstanceState != null && !savedInstanceState.isEmpty())
mDay = Day.findDayById(UUID.fromString(savedInstanceState.getString(DAY_ID)));
else
mDay = new Day(Calendar.getInstance().getTime());
adapter = new RecyclerViewAdapter(getActivity(), new ArrayList<Event>());
adapter.updateDataSet(mDay.getEvents());
adapter.notifyDataSetChanged();
}
And here's where I recieve the results in the fragment:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode != Activity.RESULT_OK)
return;
UUID eventId = (UUID)data.getSerializableExtra(EventCreatorFragment.EX_EVENT_ID);
Event event = mDay.findEventById(eventId);
switch (requestCode){
case RC_EDIT:{
int previousPosition = adapter.getPreviousPosition(eventId);
if(previousPosition == mDay.getIndex(event))
adapter.notifyItemChanged(mDay.getIndex(event));
else {
adapter.updateDataSet(mDay.getEvents());
adapter.notifyItemMoved(previousPosition, mDay.getIndex(event));
}
} break;
case RC_ADD:{
adapter.updateDataSet(mDay.getEvents());
adapter.notifyItemInserted(mDay.getIndex(event));
} break;
}
}
Here's where I set the result, in the fragment of the activity which creates\edits new elements:
public void sendResult(){
Intent data = new Intent();
data.putExtra(EX_EVENT_ID, mThisEvent.getId());
getActivity().setResult(Activity.RESULT_OK, data);
}
A few things worth noting:
As I said, adding new elements work just fine.
When an element is clicked, it sends for the EvenetCreatorActivity just fine, and there it shows the data has been edited successfuly (The various values change).
I traced through the code, and onActivityResult() isn't called at all after editing an element.
I've read online that it's possible that the activity that's supposed to get the results is destroyed for some reason, but it isn't the case.
Would appreciate your help.
You will receive at onActivityResult at Fragment only if you used the fragment context for startActivityForResult but you are using Activity... the onActivityResult will get back to the Activity that is the context from the adapter.
I'm making my first android app using android studio. In this APP I have a listview with 12 classes(12 items). After clicking on one class, it goes into a tabbed activity with 10 items of this class. On each tab page I have a rating bar to let people rate the item.
I set an activity for the listview, and 12 independent activities for those 12 tabbed activities. The code from listview to each tabbed activity is like this:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
if(i==0){
Intent intent = new Intent(ListViewActivity.this, TabbedActivity1.class);
intent.putExtra("styleName", STYLE_NAMES[i]);
intent.putExtra("styleExample",STYLE_EXAMPLES[i]);
startActivity(intent);
}
else if(i==1){
Intent intent = new Intent(ListViewActivity.this, TabbedActivity2.class);
intent.putExtra("styleName", STYLE_NAMES[i]);
intent.putExtra("styleExample",STYLE_EXAMPLES[i]);
startActivity(intent);
}
...... // skip the other 10 tabbed activities.
}
Now the problem is: after I finish rating on the tabbed activities, I return to the ListView activity and click into each tabbed activity again, the ratings are gone.
I guess the reason is that in my code, each time I click on the item it opens a new tabbed activity, although same layout, the contents are not saved.
So I was wondering whether I should do something on the ListView activity to save the ratings. I have searched for relevant questions, but I found in their scenarios, each list item is just a simple ratingbar. But here, my list item is a tabbed activity with 10 ratingbars.
Therefore, I have no idea how to do it. I have no experience in android studio, so I don't know where to start to solve the problem. Any idea is appreciated! Thanks a lot in advance!!
First of all if all your tab activities are similar you can just create one activity instead of that many in your case 12 and pass the specific content and states via intent.
The basic approach to your question is would be store rating states in your main activity and when you open your tab activity each time you click the list items send the rate of the relevant activity with intent. Then in your tab activity update the rate with it.
To achieve this we are going to use startActivityForResult instead of startActivity because we need tab activity to return last state of rating bars.
You can see the basic example shown below here:
public class ListViewActivity extends AppCompatActivity {
private static final int REQUEST_RATE = 1;
private SparseIntArray rates = new SparseIntArray();
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Intent intent = new Intent(ListViewActivity.this, TabActivity.class);
intent.putExtra("styleName", STYLE_NAMES[i]);
intent.putExtra("styleExample", STYLE_EXAMPLES[i]);
intent.putExtra("position", i);
intent.putExtra("rating", rates.get(i, 0));
startActivityForResult(intent, REQUEST_RATE);
}
}
}
#Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_RATE:
if(resultCode == RESULT_OK) {
//retrieve and save rates
Bundle extras = data.getExtras();
int position = extras.getInt("position");
int rating = extras.getInt("rating");
rates.put(position, rating);
}
break;
}
}
}
public class TabActivity extends AppCompatActivity {
private RatingBar ratingBar;
private int position;
#Override protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab);
Bundle extras = getIntent().getExtras();
position = extras.getInt("position");
int rating = extras.getInt("rating");
ratingBar.setRating(rating);
}
#Override protected void onDestroy() {
//send current rating to list activity before we leave
setResult();
super.onDestroy();
}
private void setResult() {
Intent intent = new Intent();
intent.putExtra("position", position);
intent.putExtra("rating", ratingBar.getRating());
setResult(RESULT_OK, intent);
}
}
Activity A has a listView , Activity B has a checkBox and save button.
When save button in B is clicked, it will return to Activity A. When the list in Activity A is pressed, how to show the check box is checked in Activity B if it is checked before return to A ?
Activity B
if(getIntent().getExtras()!=null) // when Activity A list is pressed
{
final String from = getIntent().getStringExtra("from");
travelFrom.setText(from);
// how to show check box is checked ?
}
save.setOnClickListener(new View.OnClickListener() { // if save button clicked, return from and outstation to A
#Override
public void onClick(View v) {
String from=travelFrom.getText().toString();
returnIntent.putExtra("from", from);
if(checkbox.isChecked()) {
returnIntent.putExtra("outstation", checkbox.getText().toString());
}
}
});
Activity A
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { // if listView is clicked
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
mClickedPosition = position;
Object o = listview.getItemAtPosition(position);
SearchResults fullObject = (SearchResults) o;
String from=fullObject.getFrom();
Intent i = new Intent(getApplication(),B.class);
i.putExtra("from",from);
startActivityForResult(i, PROJECT_REQUEST_CODE);
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { // receive from Activity B and populate ListView A
if (resultCode == RESULT_OK) {
if (requestCode == PROJECT_REQUEST_CODE) {
from=data.getStringExtra("from");
check=data.getStringExtra("outstation");
objMyCustomBaseAdapter.addNewItem(from,check); // save from and "outstation" into MySQL
}
}
}
When I press the list in A to B, the check box always not checked. How to make it check ?
Do something like implementing setOnclicklistner for checkbox. and assume an int variable to be zero. and when ever we click the checkbox increase the number by 1 every time. When we are moving from one activity to another send the data of int variable to Activity B. check Activity check the condition int variable as variable%2 if the value is equal to 1 the check box is checked. else it is not.
Assuming you have some object with this...
class MyData {
private boolean check;
public boolean getCheck() { return check; }
}
Here is some rough pseudo-code to demonstrate the concept, so not copy-paste worthy
Activity A - Pass in the boolean value that you want to the next activity
class ActivityA {
private ListView listView
onCreate() {
listView = (ListView) findViewById(R.id.list);
ArrayAdapter adapter = new ArrayAdapter();
listView.setAdapter(adapter);
listView.setOnItemClickListener( new ItemClickListener() {
onClick(int position) {
MyData listObject = adapter.getItem(position);
boolean checked = listObject.getCheck();
Intent i = new Intent(ActivityA.this, ActivityB.class);
i.putExtra("checkTheBox", check);
startActivity(i);
}
});
}
}
Activity B - Get the value out of the intent and set the checkbox to checked
class ActivityB {
private Checkbox checkbox;
onCreate() {
checkbox = (Checkbox) findViewById(R.id.checkbox);
Bundle extras = getIntent().getExtras();
if (extras != null) {
checkbox.setChecked(extras.getBooleanExtra("checkTheBox"));
}
}
}
You have to save the checked status for the selected list item when returning back from Activity B to Activity A.
In order to do that, you can simply store information in Activity A for the currently selected list item.
(for example TreeMap<View, Boolean> - item-> isSelected)
Then in onActivityResult you can set if there has been a check or not for the last selected item. When selecting again, before you create the intent you can check if this item has already been selected.
To know ActivityA ListItem is checked in ActivityB (ie CheckBox) or not. Check this below code hope this helps
ActivityA stuff
int selectedPosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//your UI setup and findViewById stuff
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedPosition = position;
startActivityForResult(activityBIntent, REQ_CODE);
}
});
}
int REQ_CODE = 7;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQ_CODE)
if (resultCode == RESULT_OK) {
adapter.changeStatus(selectedPosition, true);//update adapter
} else {
//checkbox not checked
adapter.changeStatus(selectedPosition, false);//update adapter
}
}
ActivityB stuff
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//your UI stuff
setResult(RESULT_CANCELED);//default
//check box setup and save button onclick listener
}
#Override
public void onClick(View v) {
if(v.getId()==R.id.save_button){
if (checkBox.isChecked())
setResult(RESULT_OK);
else
setResult(RESULT_CANCELED);//default
finish();//finish ActivityB and take the result to ActivityA
}
}
I have a list view with data base and when i click on an item on the list i want to move to edit page activity in order to update the item.
What am i doing wrong?
There is my code:
//by pressing a short press on any item the user moved to the edit page in order to edit his note
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
intent=new Intent(MainActivity.this,Edit_Note.class);
intent.putExtra("item_id", list.get(position).getId());
intent.putExtra("position", position);
intent.putExtra("item_title", list.get(position).getTitle().toString());
intent.putExtra("item_content", list.get(position).getContent().toString());
startActivityForResult(intent, FLAG_FOR_EDITING);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==ADD_FLAG && resultCode==RESULT_OK ){
//i am getting the information (title and content) from the edit note activity
String the_title=data.getStringExtra("user_title");
String the_content=data.getStringExtra("user_content");
//the information is added to the database
database.addNote(the_title,the_content);
}
else if(requestCode==ADD_FLAG && resultCode==RESULT_CANCELED){
Toast.makeText(MainActivity.this, "no changes have been made", Toast.LENGTH_LONG).show();
}
else if
(requestCode==FLAG_FOR_EDITING && resultCode==RESULT_OK){
int position_from_edit=data.getIntExtra("position", -2);
String title_editing=data.getStringExtra("user_title");
String content_editing=data.getStringExtra("user_content");
database.editNote("position_from_edit", title_editing, content_editing);
}
edit_title=(EditText)findViewById(R.id.edit_title);
edit_content=(EditText)findViewById(R.id.edit_content);
ImageButton save=(ImageButton)findViewById(R.id.save);
ImageButton clear=(ImageButton)findViewById(R.id.clear);
String received_title=intent.getStringExtra("item_title");
String received_content=intent.getStringExtra("item_content");
item_id=String.valueOf(intent.getIntExtra("item_id", -1));
edit_title.setText(received_title);
edit_content.setText(received_content);
//by pressing the save button, the information is sending to the main activity page
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
//i am receiving the text that the user entered to the title and to the content fields
entered_title=edit_title.getText().toString();
entered_content=edit_content.getText().toString();
intent.putExtra("position", item_id);
intent.putExtra("user_title", entered_title);
intent.putExtra("user_content", entered_content);
setResult(RESULT_OK, intent);
finish();
}
}
When you want to pass so much data through an activity, it is best to bind that data into a bundle. You should store all your data into a bundle and then bind it to the intent and then pass in the activity.
Bundle value=new Bundle;
value.putString("item_title", list.get(position).getTitle().toString());
value.putString("item_content", list.get(position).getContent().toString());
value.putInt("item_id", list.get(position).getId());
value.putInt("position", position);
intent.putExtras(value);
startActivityForResult(intent,0);
I have an app that has a few tabs. These tabs are all fragments. On the first tab fragment, I have a text view and a button, which I press on to call an activity.
This activity displays a list of items, car names.
I want to be able to click on a car in the list and return back to the calling fragment and update the text view with the car name I selected.
Can anyone help me out with this?
startActivityForResult() is probably what you're looking for. So a quick example (making super-basic assumptions about your data structure -- substitute as required) would be to make your fragment override onActivityResult(), define a request code, and then start the activity using that request code:
// Arbitrary value
private static final int REQUEST_CODE_GET_CAR = 1;
private void startCarActivity() {
Intent i = new Intent(getActivity(), CarActivity.class);
startActivityForResult(i, REQUEST_CODE_GET_CAR);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// If the activity result was received from the "Get Car" request
if (REQUEST_CODE_GET_CAR == requestCode) {
// If the activity confirmed a selection
if (Activity.RESULT_OK == resultCode) {
// Grab whatever data identifies that car that was sent in
// setResult(int, Intent)
final int carId = data.getIntExtra(CarActivity.EXTRA_CAR_ID, -1);
} else {
// You can handle a case where no selection was made if you want
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
Then, in the CarActivity, wherever you set a click listener for your list, set the result and pass back whatever data you need in an Intent:
public static final String EXTRA_CAR_ID = "com.my.application.CarActivity.EXTRA_CAR_ID";
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Assuming you have an adapter that returns a Car object
Car car = (Car) parent.getItemAtPosition(position);
Intent i = new Intent();
// Throw in some identifier
i.putExtra(EXTRA_CAR_ID, car.getId());
// Set the result with this data, and finish the activity
setResult(RESULT_OK, i);
finish();
}
call startActivityForResult(theIntent, 1);
In the activity started, once the user selects a car, make sure to put the car in an intent and set the result of the activity to that intent
Intent returnIntent = new Intent();
returnIntent.putExtra("result", theCar);
setResult(RESULT_OK, returnIntent);
finish();
Then, in your fragment, implement onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String result = data.getStringExtra("result");
}
if (resultCode == RESULT_CANCELED) {
//Write your code if there's no result
}
}
} //onActivityResult
Make Sure to override onActivityResult() in the fragment's hosting activity too, and call the super
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
This is because the parent activity hijacks the onActivityResult method, and if you don't call super() then it wont get passed to the fragment to handle it