Android getIntent gets old data instead on new one - android

I am newbie in android app.I am developing a chat application.I have used a RecyclerView and inside recyclerview adapter i am passing one data on start of a activity
That is my code below
ChatAdapter.java
//MyViewHolder
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView name;
ImageView img,status;
public MyViewHolder(View itemView) {
super(itemView);
name= (TextView) itemView.findViewById(R.id.name);
img= (ImageView) itemView.findViewById(R.id.img);
status=(ImageView)itemView.findViewById(R.id.status);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int position=getAdapterPosition();
UsersList current=data.get(position);
Intent intent=new Intent(context,ChatRoomActivity.class);
intent.putExtra("NAME",current.name);
intent.putExtra("USERNAME",current.username);
**Log.wtf("CAAAAA","USERNAME "+current.username);**
context.startActivity(intent);
}
}
Whenever i click on recycler view then it is passing correct data but when i press back button and clicks on recylclerview(other) then it is passing wrong data
I have checked via Log(Bold one),there correct data is shown but i dont know why wrong data is received in activity.
Please help me.Your response will be highly valuable for me

getAdapterPosition()
Returns the Adapter position of the item represented by this ViewHolder.
Note
that this might be different than the getLayoutPosition() if there are pending adapter updates but a new layout pass has not happened yet.
RecyclerView does not handle any adapter updates until the next layout traversal. This may create temporary inconsistencies between what user sees on the screen and what adapter contents have. This inconsistency is not important since it will be less than 16ms but it might be a problem if you want to use ViewHolder position to access the adapter. Sometimes, you may need to get the exact adapter position to do some actions in response to user events. In that case, you should use this method which will calculate the Adapter position of the ViewHolder.

I got the solution!! Actually the reason for old intent data is broadcast receiver.The broadcast receiver sends old data when activity is resumed.So therefore,we need to unregisted the broadcast receivers
Here's my code below
#Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(messageReceiver2);
LocalBroadcastManager.getInstance(this).unregisterReceiver(messageReceiver3);
LocalBroadcastManager.getInstance(this).unregisterReceiver(messageReceiver4);
super.onDestroy();
}

Use getIntent().getStringExtra("USERNAME") in Target activity.
EDIT :
UsersList current =new UsersList();
current.name=getIntent().getStringExtra("NAME");
current.username=getIntent().getStringExtra("USERNAME");
new Thread(new Runnable() { (At)
Override public void run() {
adapter=new ChatroomAdapter(ChatRoomActivity.this,dbHelperChatRoom.getMessages(current))‌​;
runOnUiThread(new Runnable() {
#Override public void run()
{ recyclerView.setAdapter(adapter);
} }); } }).start();

You need to change the Action Name for the activity in your manifest.
It should be <action android:name="android.intent.action.VIEW" /> rather than <action android:name="android.intent.action.MAIN" />
The docs for android.intent.action.MAIN state the following: Activity Action: means that this activity is the entry point of the application, i.e. when you launch the application, this activity is created, does not expect to receive data.

Related

Passing data from one activity to interactor of another activity

I'm developing a chat application. There are chatrooms and inside these rooms there are messages. When a user clicks on the chatroom I want to go to another activity where messages are displayed.
In my adapter class, I have this onclick() method written in onBindViewHolder where I would normally make an intent along with the data I need. Something like this:
#Override
public void onBindViewHolder(#NonNull ChatRoomAdapter.ChatRoomViewHolder holder, final int position) {
holder.mRoomTitle.setText(mChatRooms.get(position).getTitle());
holder.mRoomDescription.setText(mChatRooms.get(position).getDescription());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(this, NextActivity.java);
intent.putExtra("test", mChatRooms.get(position).getTitle());
}
});
}
But I'm trying the MVP architecture design and I want to pass roomTitle to the Interactor/presenter class of my next activity. How can I achieve this?
In RecyclerView adapter you need to pass a onItemClickListener in the adapter.
Refer to the Google's MVP sample - > https://github.com/googlesamples/android-architecture/tree/todo-mvp/
Especially refer the TaskItemListener in TaskFragment. They are doing the same thing what you are trying to achieve. In this they open Task details (new activity) from List of tasks(recyclervView).
/**
* Listener for clicks on tasks in the ListView.
*/
TaskItemListener mItemListener = new TaskItemListener() {
#Override
public void onTaskClick(Task clickedTask) {
mPresenter.openTaskDetails(clickedTask);
}
#Override
public void onCompleteTaskClick(Task completedTask) {
mPresenter.completeTask(completedTask);
}
#Override
public void onActivateTaskClick(Task activatedTask) {
mPresenter.activateTask(activatedTask);
}
};
And then pass it to adapter of Recycler view
mListAdapter = new TasksAdapter(new ArrayList<Task>(0), mItemListener);
And on item click
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mItemListener.onTaskClick(task);
}
});
Follow this article to know more about MVP.
You can do one thing that creates a method in the next activity's presenter
setRoomTitle(String roomTitle);
Whenever, you click and send intent and get in next Activity call that
mPresenter.setRoomTitle(roomTitle);
Is it make sense? So, you can sent your title or other data in next activity's presenter.
Let me know if you have more query then.
Thanks.
Happy coding :)
The adapter is only responsible for binding the view and the data together. Your business logic should go into the controller class which is your Activity or Fragment containing the RecyclerView. This way you can reuse it for any other Activity, and it also makes debugging/maintaining a lot easier since you know that your logic code is in one place.
But how do you link both together? It's simply done by implementing a callback interface and passing it to your adapter. A callback interface could be something like this:
interface OnClickCallback{
void onClick(String title);
}
Just add a member variable to your adapter class called mCallback for example and affect a reference to it through the adapter constructor or through a setter method.
You can either make your Activity implement this interface and pass itself as the reference or you can instantiate it in an object and pass it instead.
Then just write this:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onClick(mChatRooms.get(position).getTitle());
}
});
The onClick method should create an intent to your new Activity with an extra containing the title. In your new Activity's onCreate method, you can retrieve the title value by using:
String title = getIntent().getStringExtra(YOUR_TITLE_KEY_HERE);

Android RecyclerView onClick with JSON

I want to transfer to another fragment the item that I clicked on my recyclerview. I don't know how to transfer the data that I clicked on my recyclerview to another fragment. Here's my code. The data is from my JSON.
public void onBindViewHolder(ViewHolder holder, int position) {
final ListItem listItem = listItems.get(position);
holder.textViewHead.setText(listItem.getHead());
holder.textViewDesc.setText(listItem.getDesc());
Picasso.with(context)
.load(listItem.getImgUrl())
.into(holder.imageViewElliptic);
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "You clicked " + listItem.getHead(), Toast.LENGTH_LONG).show();
}
});
}
Well, first you should store your data either in a List or some other accessible data object, and I think you are doing that already since you created your adapter.
Well, you have this line:
public void onBindViewHolder(ViewHolder holder, int position) {
You can get the data from your List or something else by using the position provided by the method, like this:
YourJsonData data = yourDataSource.get(holder.getAdapterPosition());
Since you are using an onClickListener you should not call position directly, this might cause issues.
For example, in my project I use Lesson[] as my data source:
https://github.com/gi097/MyWindesheim/blob/master/app/src/main/java/com/giovanniterlingen/windesheim/view/Adapters/ScheduleAdapter.java
Once you get the data you can Intent a new Activity which creates the fragments for you. Alternatively, if there is already a Fragment present, you can update that one by notifying your Activity which then updates that particular Fragment.
Use Intent in onClick and send the whole ArrayList to the next activity
Intent intent = new Intent(context, AnotherActivity.class);
intent.putExtra("model", arrayList.get(position));
context.startActivity(intent);
And receive it in next Activity by using this code snippet.
Intent i = getIntent();
ArrayModel arrayModel = (ArrayModel) i.getSerializableExtra("model");
if (arrayModel != null) {
String head = arrayModel.getHead();
Log.d("HEAD", head);
}

Android: Call listener manually from java code

Is there any way to call a listener manually from code?
More background information: I use a Spinner and a DatePicker. With the Spinner you can choose a reason for staying at home (maybe your ill, maybe you have vacation) and with the DatePicker you can choose the date how long you will not be available. With these two pieces of information I build up a string for a TextView and show the same data in a compact way. The building process for the string is set by some listeners which recognize changes on one of the two controls and build and set up the new string.
If I start the program and read some data from a server the string will not be build (clearly because nothing changed and no listener will called).
The workaround is to build the string in my own onLoaddata() method. But I think it would be smoother way to call one listener to build the string for me. I also can "call" a listener if I just do some fake .updateDate but I don't think it’s a good idea to create useless calls...
Maybe someone of you have a good hint for me?
Use the following pattern:
public class YourActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
// Some initialization here
findViewById(R.id.some_button).setOnClickListener(this);
...
// Here you want to update your view
updateTextView();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.some_button:
// Here you also want to update your view
updateTextView();
break;
...
}
}
private void updateTextView() {
// Here you update your view
...
}
}

android - pass data from one activity to a list in a second activity

new to droid programming. im having a small problem that im sure is simply fixed but ive done some searching and a bunch of tutorials but cant seem to find just what i need so i figured id ask. My app has 2 activites, the first activity is just a simple form where a user enters course information(class title, professor..etc.)
the first activity passes the data which is supposed to be stored in a list in the second activity. problem is that only the first course gets stored in the list, after the first time nothing new gets added to the second activity. Can someone point me in the right direction please? thanks in advance
First Activity
public class CourseDetail extends Activity {
//Course c = new Course();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button save=(Button)findViewById(R.id.save);
save.setOnClickListener(onSave);
}
private View.OnClickListener onSave=new View.OnClickListener() {
public void onClick(View v) {
EditText course=(EditText)findViewById(R.id.course);
EditText professor=(EditText)findViewById(R.id.professor);
EditText location=(EditText)findViewById(R.id.location);
EditText officehrs=(EditText)findViewById(R.id.officehrs);
Intent i=new Intent(CourseDetail.this, CourseList.class);
i.putExtra("myCourse", course.getText().toString());
i.putExtra("myProfessor", professor.getText().toString());
i.putExtra("myLocation", location.getText().toString());
i.putExtra("myOfficehrs", officehrs.getText().toString());
startActivity(i);
}
};
}
Second Activity
public class CourseList extends Activity {
Button btnCourse;
List<Course> model = new ArrayList<Course>();
CourseAdapter adapter=null;
private String dCourse="";
private String dProfessor="";
private String dLocation="";
private String dOfficehrs="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clist);
ListView list =(ListView)findViewById(R.id.courses);
adapter=new CourseAdapter();
list.setAdapter(adapter);
Course c = new Course();
Bundle extras = getIntent().getExtras();
dCourse = extras !=null ? extras.getString("myCourse") :"no value entered";
dProfessor = extras !=null ? extras.getString("myProfessor") :"no value entered";
dLocation = extras !=null ? extras.getString("myLocation") :"no value entered";
dOfficehrs = extras !=null ? extras.getString("myOfficehrs") :"no value entered";
c.setCourse(dCourse);
c.setProfessor(dProfessor);
c.setLocation(dLocation);
c.setOfficeHrs(dOfficehrs);
btnCourse =(Button)findViewById(R.id.btnCourse);
btnCourse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
You are just getting the user entered value in CourseDetail activity and displaying the received value inside the CourseList activity, that means you are not storing these values permanently.
Go through this Android - Data Storage document.
When you move to 2nd activity i.e. CourseList activity, at that time fetch the data from the SQLite table and display the same. whenever you get new values from previous activity, at that time just update the list by adding the new data in ArrayList and make a call on adapter.notifyDataSetChanged()
Some suggestions:
Have your CourseList extend ListActivity instead of just Activity - check out some tutorials on that which should help you set things up correctly.
There seems to be a bit of confusion with how you're handling your lists - you have your model variable but don't seem to be doing anything with it. Again, have a look at a ListView tutorial (just google "android listview tutorial").
You seem to have figured out that you can use "intents" to pass information from one activity to another, but since you're only doing this in the onCreate() method, it's only happening once. Try doing this in your ListActivity's adapter once for each item.
Don't give up on Android, keep trying :-)
Some suggestion:
You have to add your object to the adapter: adapter.add(c); after you get the data.
Call adapter.notifyDataSetChanged() to notify the system that your data for the listView has been changed. Call list.invalidate() to refresh it.
I noticed that you set the button with the finish() method. Hmm, if you do so, the next time you get to CourseList Activity from CourseDetail, the adapter will be null again. No previously received data will be available. Is this what you really want?
The problem is you are not adding the newly added items to the List.So before setting adapter you have to add all your objects like
list.add(c);

Android (student cw) in need of direction

public class Menu extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle icicle) {
//myIntent.setClassName("hello.World", "hello.World.mybuttonclick");
// myIntent.putExtra("com.android.samples.SpecialValue", "Hello, Joe!"); // key/value pair, where key needs current package prefix.
//startActivity(myIntent);
//Button myButton = (Button) findViewById(R.id.my_button);
super.onCreate(icicle);
setContentView(R.layout.main);
}
public void updateLayout(){
Intent myIntent = new Intent(Menu.this, mybuttonclick.class);
startActivity(myIntent);
// TextView sayHello = (TextView) findViewById(R.id.Hello);
}
}
Hey guys, I am a new android java student and we have to develop a simple hello world app.. I am finding some difficulty getting my onClick() activity to work, using android:Onclick in xml.. what i am trying to do is change the content view do display a simply a different layout and saying hello.. i am using setContentLayout to do this, every time i click said button tho the android app crashes out.. am i doing something wrong?
regards,
Stefan
When you set a click listener in xml you must have the method defined inside the activity you are clicking in. Lets say you set the onClick in xml to be "buttonClicked", you must create a method looking exactly like the one below.
public void buttonClicked(View view)
{
//Your code here
}
The thing to notice is that the method is a public void with only a single parameter of type View. XML defined click listeners must be like this to work. The view object in the example above is the view that was clicked.
You update layout function needs to read
public void updateLayout(View view)
In response to your question, there are a number of things that are issues causing the complication that you described. Let it first be said, that you don't have to do anything any particular way, provided that you make concessions for certain things. Android is a very flexible platform and Java, as an OOP language allows you to do things that many non OOP languages do not.
Whenever you create a "clickable" item, like a Button, if you want to have your program respond, you must have something "listen" to it. This is known as a Listener. In your case, you are looking for an OnClickListener. The OnClickListener does not have to be a part of the Activity necessarily. It just has to be a class that implements View.OnClickListener. Then, you have tell the setOnClickListener() method of the Button who its listener is. The following example shows what is necessary without your declaration in XML (but it is important).
class Menu extends Activity implements View.OnClickListener
{
public void onCreate(Bundle icicle)
{ setContentView(R.layout.main);
Button btn = (Button)findViewById(R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML);
btn.setOnClickListener(this);
}
public void onClick(View view)
{ int id = view.getId();
if (id == R.id.BUTTON_ID_AS_DEFINED_BY_YOUR_XML)
updateLayout()//Do your Click event here
}
public void updateLayout()
{ //updateLayout code...
}
}
Something that needs to be noted is the OnClick() above. Every OnClickListener must use the same signature as theOnClick() That means itmust have the same return and same arguments even if it has a different name. For what you are trying to do (in XML), you have set your android:OnClick to updateLayout. This means that `updateLayout() must be declared as follows:
public void updateLayout(View view)
Now, getting the update method to actually work: While you provide your code, we don't actually know what errors you are getting. It is always much easier to solve a problem if we have a copy of the Logcat output that includes the error you are receiving. Once, we have that we can target your error specifically and I can edit my answer to include what you may additionally need.
FuzzicalLogic

Categories

Resources