Android Fragment onAttach Error - android

i have problem on my on Attach its doing red line on him and writing me :
"overrides deprecated method in 'android.support.v4.app.Fragment' "
Please help me understand what i am doing wrong ?
ty you for all the helpers !!
package com.example.omermalka.memecreator;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
/**
* Created by omermalka on 14/11/2015.
*/
public class TopSectionFragment extends Fragment {
private static EditText TopText;
private static EditText BottomText;
TopSectionListener acitivtyCommander;
public interface TopSectionListener{
public void createMime(String top , String Bottom);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
acitivtyCommander = (TopSectionListener) activity;
}catch (ClassCastException e){
throw new ClassCastException(activity.toString());
}
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.top_section_fragment, container, false);
TopText = (EditText) view.findViewById(R.id.TopTextInput);
BottomText = (EditText) view.findViewById(R.id.BottomTextInput);
final Button button = (Button) view.findViewById(R.id.BottomTextInput);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonClicked(v);
}
}
);
return view;
}
public void buttonClicked(View v) {
acitivtyCommander.createMime(TopText.getText().toString(),BottomText.getText().toString());
}
}

You need to change
public void onAttach(Activity activity)
to
public void onAttach(Context context)
Final code:
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
acitivtyCommander = (TopSectionListener) context;
} catch (ClassCastException e){
throw new ClassCastException(context.toString());
}
}

Related

Why does RecyclerView not get updated from the LiveData in the Viewmodel?

I have a fragment (Inventory Fragment) that displays some CardView objects in a RecyclerView. These objects get their data from an Adapter after the data has been received from the ViewModel. Inside the adapter, there are certain functions that can change the Livedata. All of these functions first open another Fragment (Food Editor), and this where the new data is set to the ViewModel.
My problem is that even after this, the RecyclerView does not get the new object. I used notifyDataSetChanged(). What am I doing wrong? Is there an easier way to achieve what I am trying to do (Add, Delete, Modify and such)?
Inventory Fragment:
package com.coffeetech.kittycatch;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
import java.util.List;
public class InventoryFragment extends Fragment {
//GLOBAL VARIABLES
RecyclerView recyclerView;
FoodAdapter foodAdapter;
FloatingActionButton add_button;
FrameLayout frameLayout;
FoodViewModel foodViewModel;
//FOOD LIST
private List<Food> foodList;
public InventoryFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_inventory, container, false);
//GETTING THE FOOD VIEW MODEL
foodViewModel = new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(FoodViewModel.class); //TODO:HERE
foodList = foodViewModel.getFoods().getValue();
foodAdapter = new FoodAdapter(foodList);
recyclerView=v.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(foodAdapter);
//SETTING THE FOOD VIEW MODEL
foodViewModel.getFoods().observe(getActivity(), new Observer<List<Food>>() {
#Override
public void onChanged(List<Food> foods) {
foodAdapter.setFoods(foods);
foodList=foods;
foodAdapter.notifyDataSetChanged(); //TODO: MAKE THIS BETTER
}
});
//setting up the frameLayout
frameLayout = v.findViewById(R.id.food_editor_frame);
//setting up the Add button
add_button=v.findViewById(R.id.add_button);
add_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //for new food addition to list
openFoodEditorFragment(-1);
}
});
foodAdapter.setOnFoodcardClickListener(new FoodAdapter.OnFoodcardClickListener() {
#Override
public void deleteFood(int position) { //code that deletes current food
foodViewModel.delete(foodList.get(position));
foodAdapter.notifyItemRemoved(position);
}
#Override
public void onEdit(int position) { //code that runs the edit of each food
openFoodEditorFragment(position);
foodAdapter.notifyItemChanged(position);
}
#Override
public void decrease(int position) {
foodList.get(position).decrease();
foodViewModel.update(foodList.get(position));
foodAdapter.notifyItemChanged(position);
}
#Override
public void increase(int position) {
foodList.get(position).increase();
foodViewModel.update(foodList.get(position));
foodAdapter.notifyItemChanged(position);
}
#Override
public void setSeekBar(int position,int progress) {
foodList.get(position).setQuantity(progress);
foodViewModel.update(foodList.get(position));
foodAdapter.notifyItemChanged(position);
}
});
return v;
}
public void openFoodEditorFragment(int position){ //position = -1 for new, and an integer (position) for edit
FoodEditorFragment foodEditorFragment;
switch(position){
case -1:
foodEditorFragment = new FoodEditorFragment(foodViewModel);
break;
default:
foodEditorFragment = new FoodEditorFragment(foodList.get(position),foodViewModel);
break;
}
FragmentTransaction transaction=getFragmentManager().beginTransaction();
transaction.replace(R.id.food_editor_frame,foodEditorFragment);
transaction.commit();
}
}
RecyclerView's adapter:
package com.coffeetech.kittycatch;
import android.app.Application;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class FoodAdapter extends RecyclerView.Adapter<FoodAdapter.FoodViewHolder> {
//VARIABLE THAT CONTAINS THE FOOD LIST (array list)
public List<Food> foods;
int size;
private OnFoodcardClickListener onFoodcardClickListener;
//listener interface
public interface OnFoodcardClickListener{
void deleteFood(int position);
void onEdit(int position);
void decrease(int position);
void increase(int position);
void setSeekBar(int position, int progress);
}
public void setOnFoodcardClickListener(OnFoodcardClickListener activity){ //this is called in MainActivity
onFoodcardClickListener=activity;
}
public FoodAdapter(List<Food>foods){
this.foods=foods;
}
public static class FoodViewHolder extends RecyclerView.ViewHolder{
//VARIABLES FOR EACH WIDGET IN FOODCARD
TextView name,quantity; //to modify according to current food
ImageButton decreaseButton,increaseButton; //to hide or show
SeekBar seekbar; //according to current type
ImageButton deleteButton,editButton;
public FoodViewHolder(#NonNull View itemView, final OnFoodcardClickListener listener) {//'itemView' is the card
super(itemView);
name=itemView.findViewById(R.id.name);
quantity=itemView.findViewById(R.id.quantity);
decreaseButton=itemView.findViewById(R.id.decrease_button);
increaseButton=itemView.findViewById(R.id.increase_button);
seekbar=itemView.findViewById(R.id.seekbar);
deleteButton=itemView.findViewById(R.id.delete_button);
editButton=itemView.findViewById(R.id.edit_button);
editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener!=null){
int position=getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.onEdit(position);
}
}
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener!=null){
int position=getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.deleteFood(position);
}
}
}
});
decreaseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener!=null){
int position=getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.decrease(position);
}
}
}
});
increaseButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener!=null){
int position=getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.increase(position);
}
}
}
});
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if(listener!=null){
int position=getAdapterPosition();
if (position!= RecyclerView.NO_POSITION){
listener.setSeekBar(position,seekBar.getProgress());
}
}
}
});
}
}
#NonNull
#Override
public FoodViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.foodcard, parent, false); //inflating Foodcard
FoodViewHolder vw = new FoodViewHolder(v,onFoodcardClickListener);
return vw;
}
#Override
public void onBindViewHolder(#NonNull FoodViewHolder holder, int position) { //'holder' is the foodcard here
Food currentFood=foods.get(position);
holder.name.setText(currentFood.getName());
holder.quantity.setText(String.valueOf(currentFood.getQuantity()));
holder.seekbar.setProgress(currentFood.getQuantity());
//code to hide or show certain widgets based on food type
if(currentFood.getType()==0){ //for discrete food
holder.increaseButton.setVisibility(View.VISIBLE);
holder.decreaseButton.setVisibility(View.VISIBLE);
holder.quantity.setVisibility(View.VISIBLE);
holder.seekbar.setVisibility(View.GONE);
}else{// for continuous food
holder.increaseButton.setVisibility(View.GONE);
holder.decreaseButton.setVisibility(View.GONE);
holder.quantity.setVisibility(View.GONE);
holder.seekbar.setVisibility(View.VISIBLE);
}
}
#Override
public int getItemCount() {
return size;
}
//FUCNTION TO GET LIVE DATA HERE
public void setFoods (List<Food> foods){
this.foods=foods;
notifyDataSetChanged();
}
}
Food Editor Fragment:
package com.coffeetech.kittycatch;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
public class FoodEditorFragment extends Fragment {
private TextView name,quantity,min_quantity;
private ImageButton save,cancel;
private RadioGroup radioGroup;
protected int t,mode;
protected Food food;
FoodViewModel foodViewModel;
public FoodEditorFragment() {
// Required empty public constructor
}
public FoodEditorFragment (Food food, FoodViewModel foodViewModel){
this.food=food;
this.foodViewModel=foodViewModel;
mode=1;
}
public FoodEditorFragment (FoodViewModel foodViewModel){
this.foodViewModel=foodViewModel;
this.food = new Food();
mode=0;
}
#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_food_editor, container, false);
name=view.findViewById(R.id.name_editor);
quantity=view.findViewById(R.id.quantity_editor);
min_quantity=view.findViewById(R.id.min_quantity_editor);
save=view.findViewById(R.id.save_button_editor);
cancel=view.findViewById(R.id.cancel_button_editor);
radioGroup=view.findViewById(R.id.radioGroup_editor);
if (mode==1){ //for editing Food
//CODE TO SETUP EDITOR ACCORDING TO INITIAL DETAILS
name.setText(food.getName());
quantity.setText(String.valueOf(food.getQuantity()));
min_quantity.setText(String.valueOf(food.getMin_quantity()));
t=food.getType();
if(t==0){//for discrete food
radioGroup.check(R.id.discrete_radioButton);
}else{//for cont food
radioGroup.check(R.id.cont_radioButton);
}
}
setButtons();
return view;
}
public void setButtons(){
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //USE BELOW 'food' TO PASS NEW DATA TO ACTIVITY
try {
if ((!name.getText().toString().isEmpty()) && ((radioGroup.getCheckedRadioButtonId() == R.id.discrete_radioButton) || (radioGroup.getCheckedRadioButtonId() == R.id.cont_radioButton))) {
food.setName(name.getText().toString());
food.setQuantity(Integer.parseInt(quantity.getText().toString()));
food.setMin_quantity(Integer.parseInt(min_quantity.getText().toString()));
if (radioGroup.getCheckedRadioButtonId() == R.id.discrete_radioButton) {
food.setType(0);
} else if (radioGroup.getCheckedRadioButtonId() == R.id.cont_radioButton) {
food.setType(1);
}
switch (mode){
case 0:
foodViewModel.insert(food);
break;
case 1:
foodViewModel.update(food);
break;
}
//CLOSE THE FRAGMENT
getFragmentManager().beginTransaction().remove(FoodEditorFragment.this).commit();
} else {
throw new Exception();
}
}catch (Exception e){
Toast.makeText(getContext(),"Please set all details",Toast.LENGTH_SHORT).show();
}
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { //CODE IF USER PRESSES ON CANCEL
//CLOSE THE FRAGMENT
getFragmentManager().beginTransaction().remove(FoodEditorFragment.this).commit();
}
});
}
}
ViewModel I am using:
package com.coffeetech.kittycatch;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.ArrayList;
import java.util.List;
public class FoodViewModel extends AndroidViewModel {
private FoodRepository repository;
private LiveData<List<Food>> foods;
public FoodViewModel(#NonNull Application application) {
super(application);
repository = new FoodRepository(application);
foods=repository.getAll();
}
public void insert(Food food){
repository.insert(food);
}
public void update(Food food){
repository.update(food);
}
public void delete(Food food){
repository.delete(food);
}
public void deleteAll(){
repository.deleteAll();
}
public LiveData<List<Food>> getFoods(){
return foods;
}
public LiveData<List<Food>> getBuying () {return repository.getBuying();}
}
In FoodAdapter's getItemCount() method, You set itemcount static. You have to change it to foods.size()

why should i downcast the context as an instance of the interface?

I just started to learn the fragment API on Android.
I want just to send a message back to my containing activity(I did it). Now I want to clear a misunderstanding about downcasting.
Here is my fragment:
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class DetailFragment extends Fragment {
private EditText textFirstName, textLastName, textAge;
private FragmentListener mListener;
public DetailFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (!(context instanceof FragmentListener)) throw new AssertionError();
mListener = (FragmentListener) context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
textFirstName = (EditText) rootView.findViewById(R.id.textFirstName);
textLastName = (EditText) rootView.findViewById(R.id.textLastName);
textAge = (EditText) rootView.findViewById(R.id.textAge);
Button doneButton = (Button) rootView.findViewById(R.id.done_button);
doneButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
done();
}
});
return rootView;
}
private void done() {
if (mListener == null) {
throw new AssertionError();
}
String firstName = textFirstName.getText().toString();
String lastName = textLastName.getText().toString();
int age = Integer.valueOf(textAge.getText().toString());
mListener.onFragmentFinish(firstName, lastName, age);
}
public interface FragmentListener {
void onFragmentFinish(String firstName, String lastName, int age);
}
}
I don't understand the downcasting here:
mListener = (FragmentListener) context;
How Context class relate to my FragmentListener interface?
I find this is contradictory to my knowledge about downcasting(Downcasting is casting to a subtype, downward to the inheritance tree.)
The two types, Context and FragmentListener are unrelated. However, a subclass of Context might implement the FragmentListener interface. Your onAttach() method checks that this is, in fact, what's happening and does the downcast so the FragmentListener functionality is available through the mListener member field.
Any Context (most likely an Activity) that attaches an instance of DetailFragment will need to implement DetailFragment.FragmentListener to avoid an AssertionError at run time.

Fragment dynamic layout save ui changes screen orientation

I am trying to maintain the ui changes so that when restarting the activity, the instance of my fragment become used with the changes of the buttons. So I found setRetainInstance(true) doesn't destroy the fragment object, however, the resulted view is destroyed. So I overrode onSaveInstance in the fragment class to save the ids of the resources that is called in the event handlers for setting it the next time the activity is created. The result was unexpected, at least for me:
1. The view of the fragment is destroyed when recreating the activity and the fragments instance become reattached to the new activity instance.
2. Event handlers become non-operational, so I don't know where is the problem.
Here is the code of the activity class:
package com.voicenoteinc.ticatactoy;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.PersistableBundle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
Tic_Fragment s;
FragmentManager manager;
String TAG_FRAGMENT = "tag_fragment";
FragmentTransaction trans;
boolean retained = true;
String COLOR_ARRAY;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
s = (Tic_Fragment) manager.findFragmentByTag(TAG_FRAGMENT);
if(s == null){
s = new Tic_Fragment();
retained = false;
trans = manager.beginTransaction();
trans.add(R.id.fragment_container,s,TAG_FRAGMENT).commit();
}
}
}
and Here is the code for the Fragment class:
package com.voicenoteinc.ticatactoy;
import android.app.Fragment;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Switch;
public class Tic_Fragment extends Fragment {
public Button bu1,bu2,bu3,bu4,bu5,bu6,bu7,bu8,bu9;
int COLOR[] = new int[9];
public String COLOR_KEY = "COLOR_KEY";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
for(int i =0; i<9;i++){
COLOR[i] = R.color.granite;
}
return inflater.inflate(R.layout.tic_fragment,container,false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
for(int i =0; i<9;i++){
COLOR[i] = R.color.granite;
}
super.onViewCreated(view, savedInstanceState);
if(savedInstanceState!=null){
COLOR=savedInstanceState.getIntArray(COLOR_KEY);
bu1.setBackgroundResource(COLOR[0]);
bu2.setBackgroundResource(COLOR[1]);
bu3.setBackgroundResource(COLOR[2]);
bu4.setBackgroundResource(COLOR[3]);
bu5.setBackgroundResource(COLOR[4]);
bu6.setBackgroundResource(COLOR[5]);
bu7.setBackgroundResource(COLOR[6]);
bu8.setBackgroundResource(COLOR[7]);
bu9.setBackgroundResource(COLOR[8]);
}else{
bu1 = getView().findViewById(R.id.bu1);
bu2 = getView().findViewById(R.id.bu2);
bu3 = getView().findViewById(R.id.bu3);
bu4 = getView().findViewById(R.id.bu4);
bu5 = getView().findViewById(R.id.bu5);
bu6 = getView().findViewById(R.id.bu6);
bu7 = getView().findViewById(R.id.bu7);
bu8 = getView().findViewById(R.id.bu8);
bu9 = getView().findViewById(R.id.bu9);
}
eventhandlers();
}
public void eventhandlers(){
bu1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu1,1);
}
});
bu2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu2,2);
}
});
bu3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu3,3);
}
});
bu4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu4,4);
}
});
bu5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu5,5);
}
});
bu6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu6,6);
}
});
bu7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu7,7);
}
});
bu8.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu8,8);
}
});
bu9.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
display(bu9,9);
}
});
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putIntArray(COLOR_KEY,COLOR);
}
public void display(Button bu, int i){
int backgroundColor = R.color.greenery;
bu.setBackgroundResource(backgroundColor);
COLOR[i-1] = backgroundColor;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
}
Thank ou for helping, and by the way I am new to using Fragments and Dynamic Layouts

E/RecyclerView: No adapter attached; skipping layout (Using Fragment)

I have been reading the different answers here on stackoverflow and on this blog post and tried to implement their solutions but I am still getting the error: No adapter attached; skipping layout.
RecyclerAdapter:
package vn.jupviec.frontend.android.monitor.app.ui.candidate;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.w3c.dom.Text;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import butterknife.BindView;
import vn.jupviec.frontend.android.monitor.app.R;
import vn.jupviec.frontend.android.monitor.app.domain.candidate.TrainingDTO;
import vn.jupviec.frontend.android.monitor.app.util.Utils;
/**
* Created by Windows 10 Gamer on 16/12/2016.
*/
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder> {
private static final String TAG = "RecyclerView";
private List<TrainingDTO> mTrainingDTOs;
private Context mContext;
private LayoutInflater mLayoutInflater;
private String today;
private static final DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
AdapterInterface buttonListener;
public RecyclerAdapter(Context context, List<TrainingDTO> datas, AdapterInterface buttonListener) {
mContext = context;
mTrainingDTOs = datas;
this.mLayoutInflater = LayoutInflater.from(mContext);
this.buttonListener = buttonListener;
}
#Override
public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.candidate_item, parent, false);
// View itemView = mLayoutInflater.inflate(R.layout.candidate_item, parent, false);
return new RecyclerViewHolder(itemView);
}
#Override
public void onBindViewHolder(RecyclerViewHolder holder, int position) {
final ObjectMapper mapper = new ObjectMapper();
final TrainingDTO trainingDTO = mapper.convertValue(mTrainingDTOs.get(position), TrainingDTO.class);
holder.tvName.setText(trainingDTO.getMaidName());
holder.status.setVisibility(View.GONE);
Date date = new Date();
String currentDate = sdf.format(date);
for (TrainingDTO.TrainingDetailDto td : trainingDTO.getListTrain()) {
today = Utils.formatDate((long) td.getTrainingDate(),"dd/MM/yyyy");
break;
}
if(currentDate.equals(today)) {
holder.status.setVisibility(View.VISIBLE);
holder.status.setText("(Mới)");
}
holder.btnHistory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mContext,R.string.msg_no_candidate_history,Toast.LENGTH_SHORT).show();
}
});
holder.btnTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
buttonListener.showComment(trainingDTO);
}
});
}
#Override
public int getItemCount() {
int size ;
if(mTrainingDTOs != null && !mTrainingDTOs.isEmpty()) {
size = mTrainingDTOs.size();
}
else {
size = 0;
}
return size;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private Button btnTest;
private Button btnHistory;
private TextView status;
public RecyclerViewHolder(View itemView) {
super(itemView);
tvName = (TextView) itemView.findViewById(R.id.txtName);
btnTest = (Button) itemView.findViewById(R.id.btnTest);
btnHistory = (Button) itemView.findViewById(R.id.btnHistory);
status = (TextView)itemView.findViewById(R.id.status);
}
}
public boolean removeItem(int position) {
if (mTrainingDTOs.size() >= position + 1) {
mTrainingDTOs.remove(position);
return true;
}
return false;
}
public interface AdapterInterface {
void showComment(TrainingDTO trainingDTO);
void showHistory(TrainingDTO trainingDTO);
}
}
FragmentTapNew:
package vn.jupviec.frontend.android.monitor.app.ui.candidate;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ClipDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
import vn.jupviec.frontend.android.monitor.app.R;
import vn.jupviec.frontend.android.monitor.app.domain.ResultDTO;
import vn.jupviec.frontend.android.monitor.app.domain.candidate.TrainingDTO;
import vn.jupviec.frontend.android.monitor.app.domain.training.CandidateService;
import vn.jupviec.frontend.android.monitor.app.util.Constants;
import vn.jupviec.frontend.android.monitor.app.util.Utils;
/**
* Created by Windows 10 Gamer on 09/12/2016.
*/
public class FragmentTapNew extends Fragment implements RecyclerAdapter.AdapterInterface {
private static final String TAG = FragmentTapNew.class.getSimpleName();
Activity myContext = null;
private OnItemSelectedListener listener;
ShapeDrawable shapeDrawable;
#BindView(R.id.lvToday)
RecyclerView lvToday;
#BindView(R.id.textView)
TextView textView;
#BindView(R.id.pb_loading)
ProgressBar pbLoading;
private Unbinder unbinder;
private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;
ArrayList<TrainingDTO> mTrainingDTO ;
RecyclerAdapter mTrainingDTOAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_candidate_training, container, false);
unbinder = ButterKnife.bind(this, v);
initViews();
return v;
}
private void initViews() {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
}
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
Toast.makeText(getActivity(), R.string.err_cannot_establish_connection, Toast.LENGTH_SHORT).show();
return false;
} else
return true;
}
private void today() {
if(isNetworkConnected()){
String token = "a";
Integer date = 0;
setLoadingVisible(true);
CandidateService.getApiDummyClient(getContext()).getCandidate(
token,
date,
Constants.TRAINING,
Arrays.asList(Constants.TRAINING_DAY_NEW),
new Callback<ResultDTO>() {
#Override
public void success(ResultDTO resultDTO, Response response) {
setLoadingVisible(false);
mTrainingDTO = (ArrayList<TrainingDTO>) resultDTO.getData();
if (mTrainingDTO.size() == 0) {
if(textView!=null) {
textView.setVisibility(View.VISIBLE);
textView.setTextColor(Color.RED);
textView.setGravity(Gravity.CENTER | Gravity.BOTTOM);
}
} else {
if(textView!=null) {
textView.setVisibility(View.GONE);
}
if(null==mTrainingDTOAdapter) {
mTrainingDTOAdapter = new RecyclerAdapter(getActivity(), mTrainingDTO, FragmentTapNew.this);
lvToday.setAdapter(mTrainingDTOAdapter);
} else {
lvToday.setAdapter(mTrainingDTOAdapter);
mTrainingDTOAdapter.notifyDataSetChanged();
}
lvToday.invalidate();
}
}
#Override
public void failure(RetrofitError error) {
Log.e(TAG, "JV-ERROR: " + error.getMessage());
Log.e(TAG, "JV-ERROR: " + error.getSuccessType());
}
});
}
}
#Override
public void onResume() {
setLoadingVisible(false);
initViews();
lvToday.setAdapter(mTrainingDTOAdapter);
super.onResume();
}
#Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
private void setLoadingVisible(boolean visible) {
// pbLoading.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY);
if(pbLoading!=null) {
pbLoading.setVisibility(visible ? View.VISIBLE : View.GONE);
lvToday.setVisibility(visible ? View.GONE : View.VISIBLE);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " phải implemenet MyListFragment.OnItemSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public void showComment(TrainingDTO trainingDTO) {
Intent intent = new Intent(getContext(), CommentActivity.class);
intent.putExtra(Constants.ARG_NAME_DETAIL, trainingDTO);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
#Override
public void showHistory(TrainingDTO trainingDTO) {
Intent intent = new Intent(getContext(), HistoryActivity.class);
intent.putExtra(Constants.ARG_CANDIDATE_HISTORY_DETAIL, trainingDTO);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
public interface OnItemSelectedListener {
void showComment(TrainingDTO trainingDTO);
void showHistory(TrainingDTO trainingDTO);
}
}
The first, you don't need to set adapter multiple time, only set adapter at the first time in your method initView().
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
if(mTrainingDTO == null) {
mTrainingDTO = new ArrayList<>();
}
if(null == mTrainingDTOAdapter ) {
mTrainingDTOAdapter = new RecyclerAdapter(getActivity(), mTrainingDTO, FragmentTapNew.this);
}
lvToday.setAdapter(mTrainingDTOAdapter);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
After that, you don't need to call lvToday.setAdapter(mTrainingDTOAdapter);
many times. Just call mTrainingDTOAdapter.notifyDataSetChanged(); if having any changes in your data mTrainingDTO.
The errorlog - error:No adapter attached; skipping layout indicates that you've attached LayoutManager but you haven't attached an adapter yet, so recyclerview will skip layout. I'm not sure but, in other words recyclerView will skip layout measuring at the moment.
to prevent this errorLog Try to set an adapter with an empty dataSet i.e. ArrayList or
Attach LayoutManager just before you are setting your adapter.
Try this,
private void initViews() {
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(getActivity());
lvToday.setLayoutManager(mLinearLayoutManager);
lvToday.setHasFixedSize(true);
lvToday.setNestedScrollingEnabled(false);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
today();
}
});
t.start();
}

Passing Boolean value from fragments to activity

I am new to android development and I am trying to pass a Boolean value from dialog fragment to the activity.
the boolean value is supposed to be decided by the user(depends on which button user clicked). However, the boolean immediately turned to false without clicking any button.
I have tried various method recommended I found on internet but none of them works for me(I guess I have some part screwed up...), these method include:
-broadcasting
-implementing interface
-intent.putExtra
and below is the code that I have came up with, could anyone help me take a look? Any help is appreciated.
Stage:
package com.example.fuj.valorsafeworldbytrade;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import static com.example.fuj.valorsafeworldbytrade.LosingDialogFragment.LOSING_FRAGMENT;
public class Stage extends AppCompatActivity {
String stage;
FragmentManager fragmentManager = getSupportFragmentManager();
LosingDialogFragment losingDialogFragment = new LosingDialogFragment();
BasicInfo basicInfo = new BasicInfo();
public void setText(){
TextView cpuReputation = (TextView) findViewById(R.id.cpu_reputation);
TextView cpuGold = (TextView) findViewById(R.id.cpu_gold);
TextView pGoldText = (TextView) findViewById(R.id.player_gold);
TextView pRepText = (TextView) findViewById(R.id.player_reputation);
cpuReputation.setText(String.valueOf(basicInfo.cRep));
cpuGold.setText(String.valueOf(basicInfo.cGold));
pGoldText.setText(String.valueOf(basicInfo.pGold));
pRepText.setText(String.valueOf(basicInfo.pRep));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stage);
setText();
}
protected void onStart() {
super.onStart();
stage = getIntent().getStringExtra(StageChoosingMenu.STAGE);
}
public void playerChoice(View view) {
boolean deceiveEnabled;
switch (view.getId()) {
case R.id.cooperate_button:
deceiveEnabled = false;
break;
case R.id.deceive_button:
deceiveEnabled = true;
break;
default:
throw new RuntimeException("Unknown Button ID");
}
switch (stage){
case "xumo":
xuMo(deceiveEnabled);
break;
}
}
public void xuMo(boolean playerDeceiveEnabled){
boolean cpuDeceiveEnabled;
cpuDeceiveEnabled = (Math.random() - basicInfo.faith > 0);
if (cpuDeceiveEnabled){
if (playerDeceiveEnabled){
basicInfo.playerDvsCpuD();
// faith changes to be amend w/ proper value, need record on the change of status
}
if (!playerDeceiveEnabled){
basicInfo.playerCvsCpuD();
}
}
if (!cpuDeceiveEnabled){
if (playerDeceiveEnabled){
basicInfo.playerDvsCpuC();
}
if (!playerDeceiveEnabled){
basicInfo.playerCvsCpuC();
}
}
if(basicInfo.pGold <= 0 || basicInfo.cGold <= 0 || basicInfo.pRep <= 0 || basicInfo.cRep <= 0){
//to be changed
setText();
losingDialogFragment.show(fragmentManager,LOSING_FRAGMENT);
//trying to show a alert dialog fragment
Log.d("True", String.valueOf(losingDialogFragment.tryAgainEnabled));
if(losingDialogFragment.tryAgainEnabled){//tryAgainEnabled is always false
//This is the part that I wanted to retrieve data from the user(if they want to try again or not)
basicInfo.reset();
losingDialogFragment.dismiss();
}else{
losingDialogFragment.dismiss();
}
}
setText();
// to be changed
}
}
LosingDialogFragment:
package com.example.fuj.valorsafeworldbytrade;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
/**
* Created by fuj on 20/1/2017.
*/
public class LosingDialogFragment extends DialogFragment{
public static final String LOSING_FRAGMENT = "LOSING";
public boolean tryAgainEnabled;
Intent intent = new Intent();
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_lose, container, false);;
//the following code is used to set the boolean value after the user click the button
final Button tryAgainButton = (Button)rootView.findViewById(R.id.try_again_button);
tryAgainButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tryAgainEnabled = true;
}
});
Button giveUpButton =(Button)rootView.findViewById(R.id.give_up_button);
giveUpButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tryAgainEnabled = false;
}
});
getDialog().setTitle(LOSING_FRAGMENT);
return rootView;
}
}
I am also sorry that I am not the best with English, if any things is not clear or not polite because of my poor English, please kindly let me know. I apologize in advance for any mistakes I have made.
It's because you check the value of tryAgainEnabled exactly right after showing the Dialog. Dialog starts Asynchronously, It means that it starts in diffrent Thread and your current thread doesn't wait for dismissing Dialog, So this line of your code if(losingDialogFragment.tryAgainEnabled){ runs exactly after you show dialog, befor you set value to tryAgainEnabled. Because the default value of boolean is always false, you will get false everytime.
I suggest that use listener for this:
Dialog:
public class LosingDialogFragment extends DialogFragment {
public static final String LOSING_FRAGMENT = "LOSING";
public boolean tryAgainEnabled;
Intent intent = new Intent();
private View.OnClickListener onTryAgainButtonClickLisnter;
private View.OnClickListener onGiveUpButtonClickLisnter;
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_lose, container, false);;
final Button tryAgainButton = (Button)rootView.findViewById(R.id.try_again_button);
tryAgainButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(onTryAgainButtonClickLisnter!=null)
onTryAgainButtonClickLisnter.onClick(v);
}
});
Button giveUpButton =(Button)rootView.findViewById(R.id.give_up_button);
giveUpButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(onGiveUpButtonClickLisnter!=null)
onGiveUpButtonClickLisnter.onClick(v);
}
});
getDialog().setTitle(LOSING_FRAGMENT);
return rootView;
}
public void setOnTryAgainButtonClickLisnter(View.OnClickListener onTryAgainButtonClickLisnter) {
this.onTryAgainButtonClickLisnter = onTryAgainButtonClickLisnter;
}
public void setOnGiveUpButtonClickLisnter(View.OnClickListener onGiveUpButtonClickLisnter) {
this.onGiveUpButtonClickLisnter = onGiveUpButtonClickLisnter;
}
}
In your activity call dialog like this:
LosingDialogFragment losingDialogFragment = new LosingDialogFragment();
losingDialogFragment.setOnTryAgainButtonClickLisnter(new View.OnClickListener() {
#Override
public void onClick(View v) {
tryAgain();
losingDialogFragment.dismiss();
}
});
losingDialogFragment.setOnGiveUpButtonClickLisnter(new View.OnClickListener() {
#Override
public void onClick(View v) {
giveUp();
losingDialogFragment.dismiss();
}
});
losingDialogFragment.show(fragmentManager, "");
Declare public boolean tryAgainEnabled; in your Stage Activity and youd can update that variable using ((Stage)context).tryAgainEnabled.
package com.example.fuj.valorsafeworldbytrade;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import static com.example.fuj.valorsafeworldbytrade.LosingDialogFragment.LOSING_FRAGMENT;
public class Stage extends AppCompatActivity {
String stage;
FragmentManager fragmentManager = getSupportFragmentManager();
LosingDialogFragment losingDialogFragment = new LosingDialogFragment();
BasicInfo basicInfo = new BasicInfo();
public boolean tryAgainEnabled;
public void setText(){
TextView cpuReputation = (TextView) findViewById(R.id.cpu_reputation);
TextView cpuGold = (TextView) findViewById(R.id.cpu_gold);
TextView pGoldText = (TextView) findViewById(R.id.player_gold);
TextView pRepText = (TextView) findViewById(R.id.player_reputation);
cpuReputation.setText(String.valueOf(basicInfo.cRep));
cpuGold.setText(String.valueOf(basicInfo.cGold));
pGoldText.setText(String.valueOf(basicInfo.pGold));
pRepText.setText(String.valueOf(basicInfo.pRep));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stage);
setText();
}
protected void onStart() {
super.onStart();
stage = getIntent().getStringExtra(StageChoosingMenu.STAGE);
}
public void playerChoice(View view) {
boolean deceiveEnabled;
switch (view.getId()) {
case R.id.cooperate_button:
deceiveEnabled = false;
break;
case R.id.deceive_button:
deceiveEnabled = true;
break;
default:
throw new RuntimeException("Unknown Button ID");
}
switch (stage){
case "xumo":
xuMo(deceiveEnabled);
break;
}
}
public void xuMo(boolean playerDeceiveEnabled){
boolean cpuDeceiveEnabled;
cpuDeceiveEnabled = (Math.random() - basicInfo.faith > 0);
if (cpuDeceiveEnabled){
if (playerDeceiveEnabled){
basicInfo.playerDvsCpuD();
// faith changes to be amend w/ proper value, need record on the change of status
}
if (!playerDeceiveEnabled){
basicInfo.playerCvsCpuD();
}
}
if (!cpuDeceiveEnabled){
if (playerDeceiveEnabled){
basicInfo.playerDvsCpuC();
}
if (!playerDeceiveEnabled){
basicInfo.playerCvsCpuC();
}
}
if(basicInfo.pGold <= 0 || basicInfo.cGold <= 0 || basicInfo.pRep <= 0 || basicInfo.cRep <= 0){
//to be changed
setText();
losingDialogFragment.show(fragmentManager,LOSING_FRAGMENT);
Log.d("True", String.valueOf(losingDialogFragment.tryAgainEnabled));
if(losingDialogFragment.tryAgainEnabled){//tryAgainEnabled is always false
basicInfo.reset();
losingDialogFragment.dismiss();
}else{
losingDialogFragment.dismiss();
}
}
setText();
// to be changed
}
}
And in Fragment
package com.example.fuj.valorsafeworldbytrade;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
/**
* Created by fuj on 20/1/2017.
*/
public class LosingDialogFragment extends DialogFragment{
public static final String LOSING_FRAGMENT = "LOSING";
Context context;
Intent intent = new Intent();
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.fragment_lose, container, false);;
final Button tryAgainButton = (Button)rootView.findViewById(R.id.try_again_button);
tryAgainButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Stage)context).tryAgainEnabled = true;
}
});
Button giveUpButton =(Button)rootView.findViewById(R.id.give_up_button);
giveUpButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Stage)context).tryAgainEnabled = false;
}
});
getDialog().setTitle(LOSING_FRAGMENT);
return rootView;
}
}

Categories

Resources