Sharing data between an adapter-recyclerview and another class - java

I want to send in a variable the position of a click on an Item in a other activity. I show you my work that does not work. The application quits when I press an item.
MyViewHolder in my adapter:
public myViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get position
int poss = getAdapterPosition();
// sharing position
Intent intent = new Intent(mContext, Main2Activity.class);
intent.putExtra("position", poss );
mContext.startActivity(intent);
}
}
});
And my Activity for recept:
public class Main2Activity extends AppCompatActivity {
private TextView textTest;
int id = getIntent().getExtras().getInt("position");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
String position = String.valueOf(id);
textTest = findViewById(R.id.text_test);
textTest.setText(position);
}

Try
public class Main2Activity extends AppCompatActivity {
private TextView textTest;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textTest = findViewById(R.id.text_test);
int id = getIntent().getExtras().getInt("position");
String position = String.valueOf(id);
textTest.setText(position);
}

Remove this line of code int id = getIntent().getExtras().getInt("position"); from outside of the onCreate() method & put this code inside of your onCreate Method in Main2Activity
textTest = findViewById(R.id.text_test);
int id = getIntent().getExtras().getInt("position");
String position = String.valueOf(id);
textTest.setText(position);

Create Interface class
Public interface OnPostionClick{
Public void yourmethod(int pos)
}
Place interface method on Adapter viewHolder onClick method
If(context instanceof OnPostionClick){
((OnPostionClick) context).yourmethod(poss);
}
implement OnPostionClick interface on Second Activity and override yourmethod

Related

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

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

Cant get an int value from on class to another class : android studio

I'm kind of new to android. I want to get an int value id(id of dynamically generated buttons) from class MainPage into class Note when a button is clicked. but the value of id always turns to zero in Note class.
here's the summerized code:
MainPage class:
public class MainPage extends AppCompatActivity {
public int id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int j=0; j<allnotes.size(); j++) {
//generating buutons
final Button preview_text = new Button(this);
preview_text.setId(j)
preview_text.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//getting id of the clicked button
id=v.getId();
startActivity(new Intent(MainPage.this, Note.class));
}
});
}
}
}
Notes class:
public class Note extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note);
MainPage obj=new MainPage();
int id=obj.id
View parentLayout = findViewById(android.R.id.content);
Snackbar mySnackbar = Snackbar.make(parentLayout,Integer.toString(id) , 10000);
mySnackbar.show();
}
in snackbar message, id is always zero.
You need to add the id to the Intent you use to start the Note activity. You do this by using Intent.putExtra(...) and in Note you retrieve it via getIntent().getIntExtra(...)
Here I implemented #Riccully Answer in your code.
MainPage.java
preview_text.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//getting id of the clicked button
id = v.getId();
Intent intent = new Intent(MainPage.this, Note.class);
intent.putExtra("id_value", id);
startActivity(intent);
}
});
Note.java
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.note);
int id = getIntent().getIntExtra("id_value", 0);
View parentLayout = findViewById(android.R.id.content);
Snackbar mySnackbar = Snackbar.make(parentLayout, Integer.toString(id), 10000);
mySnackbar.show();
}
we can do this via intent Because Android Intent is the message that is passed between components such as activities, content providers, broadcast receivers, services, etc.
In Our case, we can send the v.getId() to Note.java, viaputExtra
intent.putExtra("view_id",v.getId());
and receive the value in Note.java by using
getIntent().getIntExtra("view_id", 0);

Object not being deleted from ListView

I am creating a simple tasklist app in Android Studios.
I have two activities as following (removed imports and package specifications):
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener, AdapterView.OnItemClickListener {
EditText taskAdd;
Button add;
public ListView tasks;
public Integer pos = 0;
public ArrayList<String> taskArray;
public ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
taskAdd = findViewById(R.id.taskAdd);
add = findViewById(R.id.add);
tasks = findViewById(R.id.tasks);
taskArray = FileHelper.readData(this);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, taskArray);
tasks.setAdapter(adapter);
add.setOnClickListener(this);
tasks.setOnItemClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.add:
String entered = taskAdd.getText().toString();
if (entered != "" || entered != null || entered != "null") {
adapter.add(entered);
taskAdd.setText("");
FileHelper.writeData(taskArray, this);
Toast.makeText(this, "Task Added!", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
pos = position;
Intent intent = new Intent(MainActivity.this, Pop.class);
startActivity(intent);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
processExtraData();
}
private void processExtraData(){
Bundle extras = getIntent().getExtras();
if (extras != null) {
int value = extras.getInt("Value");
if (value == 1) {
taskArray.remove(pos);
adapter.notifyDataSetChanged();
Toast.makeText(this, "Task Removed!", Toast.LENGTH_SHORT).show();
}
}
}
}
Pop.java (a popup)
public class Pop extends Activity implements View.OnClickListener {
Button deleteButton;
Button finishedButton;
Button timerButton;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.popwindow);
deleteButton = findViewById(R.id.deleteButton);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
getWindow().setLayout((int)(width*0.5),(int)(height*0.5));
deleteButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Intent i = new Intent(this, MainActivity.class);
i.putExtra("Value", 1);
startActivity(i);
}
}
After I click deleteButton in Pop.java, processExtraData in MainActivity.java is supposed to run. The Toast does appear, but the selected object in the ListView is not deleted. No errors are thrown either. In addition, using Log.d to check the size of taskArray confirmed that this is not just a graphical issue. Why is this the case, and how should I go about fixing it?
Thank you for replying in advance.
The issue is that you are using an object reference instead of a primitive data type, and so when you are calling taskArray.remove(pos), it is looking for pos the object rather than its denoted integer value.
Instead of:
taskArray.remove(pos);
try:
taskArray.remove(pos.intValue());

Sending a variable from a fragment to MainActivity

In my app I have three fragments. In the third fragment, a variable is take from a seekBar. Now I want to use this variable in my MainActivity. I tried to send the variable with an intent and show it in a textView onClick to test it, but the textView only shows „null“. Why isn‘t the variable send to the activity?
My MainActivity:
public class MainActivity extends AppCompatActivity {
TextView textTest;
public int a = 33;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textTest = (TextView) findViewById(R.id.textView3);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = getIntent();
String messages = intent.getStringExtra("message");
textTest.setText(String.valueOf(messages));
}
});
}
}
My Fragment that sends the variable:
public class ItemThreeFragment extends Fragment {
SeekBar seekBar;
TextView textView11;
int value = 10;
public static ItemThreeFragment newInstance() {
ItemThreeFragment fragment = new ItemThreeFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_item_three, container, false);
seekBar = (SeekBar) view.findViewById(R.id.seekBar);
seekBar.setMax(25);
seekBar.setProgress(value);
textView11 = (TextView) view.findViewById(R.id.textView11);
textView11.setText("" + value);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
value = i;
textView11.setText("" + value);
Intent intent = new Intent(getActivity().getBaseContext(),
MainActivity.class);
intent.putExtra("message", value);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
})
return view;
}
}
The problems are
In your activity, Intent intent = getIntent(); will get the intent that starts MainActivity.
In your fragment's onProgressChanged, your code doesn't communicate with MainActivity at all.
I can think of two relatively simple solutions for now:
Call a MainActivity function using ((MainActivity) getActivity()).someFunction() in your fragment.
In the MainActivity, use ((YourFragment) getSupportFragmentManager().findFragmentById(R.id.your_fragment_id)).property to access the fragment object's content. You can put the seek bar value into a class variable.
And check this: Communicating between a fragment and an activity - best practices
getActivity().findViewById(R.id.textView3).setText(""+value);
put the code inside onProgressChanged(),I hope its help you.
I think you missed startActivity(intent).
Intent intent = new Intent(getActivity().getBaseContext(),
MainActivity.class);
intent.putExtra("message", value);
getActivity().startActivity(intent);

main activity reads the data again from the firebase database after coming back to the mainactivity

this is my MainActivity
private DatabaseReference mDatabaseReference;
private RecyclerView recyclerView;
private PlaceRecyclerAdapter placeRecyclerAdapter;
private List<Places> placesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Places");
placesList = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId()==R.id.action_add)
{
startActivity(new Intent(MainActivity.this,AddPostActivity.class));
finish();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onStart() {
super.onStart();
mDatabaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Places places = dataSnapshot.getValue(Places.class);
placesList.add(places);
placeRecyclerAdapter = new PlaceRecyclerAdapter(MainActivity.this,placesList);
recyclerView.setAdapter(placeRecyclerAdapter);
placeRecyclerAdapter.notifyDataSetChanged();
}
I am using this RecyclerAdapter to load cardview cards in the main activity
public PlaceRecyclerAdapter(Context context, List<Places> placesList) {
this.context = context;
this.placesList = placesList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.post_row,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Places places = placesList.get(position);
//String imageUrl= null;
holder.place.setText(places.getPlace());
holder.desc.setText(places.getDesc());
//imageUrl= places.getImage();
//todo: Use piccasso library to load images
//Picasso.with(context).load(imageUrl).into(holder.image);
}
#Override
public int getItemCount() {
return placesList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView place;
public TextView desc;
//public ImageView image;
public ViewHolder(View view) {
super(view);
place = (TextView) view.findViewById(R.id.postTitleList);
desc = (TextView) view.findViewById(R.id.postDescList);
//image = (ImageView) view.findViewById(R.id.postImageList);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = v.getContext();
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
Places clickedDataItem = placesList.get(pos);
//Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getPlace(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, Details.class);
intent.putExtra("NAME", clickedDataItem.getPlace());
intent.putExtra("DESC", clickedDataItem.getDesc());
intent.putExtra("IMG", clickedDataItem.getImage());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
}
and here is my Details activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
dPlace = (TextView) findViewById(R.id.detail_title);
dDesc = (TextView) findViewById(R.id.detail_desc);
dImage = (ImageView) findViewById(R.id.detail_image);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String name = bundle.getString("NAME");
String desc = bundle.getString("DESC");
String img = bundle.getString("IMG");
dPlace.setText(name);
dDesc.setText(desc);
Picasso.with(this).load(img).into(dImage);
now, clicking on a item in MainActivity I am able to go to the Details activity. suppose there are 3 items in database, and at first main activity shows only 3 items. but after going to Details activity, and then coming back to main activity, there are 6 items, the earlier 3 items are repeated. and if again I go to the Details activity and come back, there will be 9 items. I used (Activity)context).finish(); in RecyclerViewAdapter to finish the main activity, but I think it finishes the context from which I am able to get the details.
please help.
Sorry for my bad english.
Your firebase loading data items needs to go inside onCreate() as it will only gets called only once if its on backstack an onStart() will get called twice. So just implement the data item loading logic in onCreate instead of onStart()
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDatabaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Places places = dataSnapshot.getValue(Places.class);
placesList.add(places);
placeRecyclerAdapter = new PlaceRecyclerAdapter(MainActivity.this,placesList);
recyclerView.setAdapter(placeRecyclerAdapter);
placeRecyclerAdapter.notifyDataSetChanged();
}
}
Update
placesList.clear();
placesList.add(places);

Categories