I am trying to make my app handle orientation changes. Right now I am working with a RecyclerView that has an CustomAdapter to handle the data. I have implemented onSaveInstanceState to save the data that is in the Adapter, but when I re-insert it after orientation change, the method onBindViewHolder is not called. I have confirmed the data is saved and the array lists are not empty and contain the data I need.
Here is the CustomAdapter:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private static final String TAG = "CustomAdapter";
private ArrayList<Words> mDataSet;
private RecyclerView mRecyclerView;
private PopupWindow mPopupWindow;
private int currentPos;
private String srcOld;
private String targetOld;
private TranslateActivityFragment mFragment;
private EditText mEditSrc;
private EditText mEditTarget;
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private TextView textView2;
private TextView textView3;
public ViewHolder(View v){
super(v);
textView = v.findViewById(R.id.adapter_textview1);
textView2 = v.findViewById(R.id.adapter_textview2);
textView3 = v.findViewById(R.id.adapter_textview3);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
mPopupWindow.showAtLocation(mRecyclerView, Gravity.CENTER,0,0);
mPopupWindow.setFocusable(true);
mPopupWindow.update();
currentPos = getAdapterPosition();
setCurrText();
}
private void setCurrText(){
Words tmp = mDataSet.get(currentPos);
srcOld = tmp.getW1();
targetOld = tmp.getW2();
mEditSrc.setText(srcOld);
mEditTarget.setText(targetOld);
}
});
}
public TextView getLeftTextView(){
return textView;
}
public TextView getCenterTextView(){return textView2;}
public TextView getRightTextView(){return textView3;}
}
public CustomAdapter(RecyclerView recyclerView, Context context, TranslateActivityFragment fragment){
mRecyclerView = recyclerView;
mDataSet = new ArrayList<Words>();
mFragment = fragment;
this.notifyDataSetChanged();
View v = LayoutInflater.from(mFragment.getActivity()).inflate(R.layout.edit_translate,null,false);
createPopupWindow(v, mFragment.getActivity());
setEditText(v);
}
private void setEditText(View v){
mEditSrc = v.findViewById(R.id.edit_src);
mEditTarget = v.findViewById(R.id.edit_target);
}
private void createPopupWindow(View v, Activity activity){
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
float width = 300*metrics.density;
float height = 200*metrics.density;
mPopupWindow = new PopupWindow(v,(int)width, (int)height);
Button buttonOk = v.findViewById(R.id.button_ok);
Button buttonCancel = v.findViewById(R.id.button_cancel);
Button buttonDelete = v.findViewById(R.id.button_delete);
buttonCancel.setOnClickListener(new CancelListener());
buttonOk.setOnClickListener(new OkListener());
buttonDelete.setOnClickListener(new DeleteListener());
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.textview_layout, viewGroup,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position){
Log.d(TAG, "Element " + position + " set." + mDataSet.get(position).getW1());
viewHolder.getLeftTextView().setText(mDataSet.get(position).getW1());
viewHolder.getCenterTextView().setText(" - ");
viewHolder.getRightTextView().setText( mDataSet.get(position).getW2());
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public void addData(Words newData, RecyclerView recyclerView){
mDataSet.add(newData);
System.out.println("------ ADDING DATA--------");
this.notifyDataSetChanged();
if (mDataSet.size() > 0) {
recyclerView.smoothScrollToPosition(mDataSet.size() - 1);
}
}
public void dismissPopup(){
mPopupWindow.dismiss();
}
public void removeWord(){
mDataSet.remove(currentPos);
System.out.println("mDataSet.size(): " + mDataSet.size());
System.out.println("mFragment.getTranslater.getData.size(): " + mFragment.getTranslater().getWords().size());
mFragment.getTranslater().deleteWord(currentPos);
this.notifyDataSetChanged();
}
// Update the current word from EditTexts
public void updateWord(){
String src = mEditSrc.getText().toString();
String target = mEditTarget.getText().toString();
mDataSet.get(currentPos).setW1(src);
mDataSet.get(currentPos).setW2(target);
mFragment.getTranslater().updateWord(src, target, currentPos);
this.notifyDataSetChanged();
}
private class OkListener implements View.OnClickListener {
#Override
public void onClick(View view) {
updateWord();
dismissPopup();
}
}
private class CancelListener implements View.OnClickListener{
#Override
public void onClick(View view){
dismissPopup();
}
}
private class DeleteListener implements View.OnClickListener{
#Override
public void onClick(View view){
removeWord();
dismissPopup();
}
}
public ArrayList<Words> getWords(){
return mDataSet;
}
public ArrayList<String> getW1List() {
ArrayList<String> tmp = new ArrayList<>();
for (Words w : mDataSet){
tmp.add(w.getW1());
}
return tmp;
}
public ArrayList<String> getW2List(){
ArrayList<String> tmp = new ArrayList<>();
for (Words w : mDataSet){
tmp.add(w.getW2());
}
return tmp;
}
//
// Here is where I try to restore data.
//
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2, RecyclerView recyclerView){
if (mDataSet == null){
mDataSet = new ArrayList<>();
}
System.out.println("Restoring words");
for (int i = 0; i < w1.size(); ++i){
Words tmp = new Words(w1.get(i), w2.get(i), 0,0,0,false);
addData(tmp, recyclerView);
}
}
}
Code in Fragment to handle the view:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new CustomAdapter(mRecyclerView, this.getContext(), this);
mRecyclerView.setAdapter(mAdapter);
if (savedInstanceState != null){
ArrayList<String> w1 = savedInstanceState.getStringArrayList(TranslateActivity.W1LIST);
ArrayList<String> w2 = savedInstanceState.getStringArrayList(W2LIST);
restoreWords(w1,w2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_translate, container, false);
mRecyclerView = root.findViewById(R.id.translate_recycle);
mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayout.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
return root;
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState){
mHelper = new Helper();
if (savedInstanceState == null) {
Intent intent = getActivity().getIntent();
source_lang = intent.getStringExtra(MainActivityFragment.SOURCE_LANG);
target_lang = intent.getStringExtra(MainActivityFragment.TARGET_LANG);
} else {
source_lang = savedInstanceState.getString(MainActivityFragment.SOURCE_LANG);
target_lang = savedInstanceState.getString(MainActivityFragment.TARGET_LANG);
}
key = mHelper.getKey(source_lang, target_lang);
mTranslater = new Translater(source_lang, target_lang, key);
setHasOptionsMenu(true);
setToolbarText();
}
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2){
System.out.println("..................RESTORE WORDS....................");
mAdapter.restoreWords(w1, w2, mRecyclerView);
}
onCreate in Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
helper = new Helper();
mInAppPurchase = new InAppPurchase(this, this);
mInAppPurchase.setUpNoQuery();
setContentView(R.layout.activity_translate);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mFragment = new TranslateActivityFragment();
View v = LayoutInflater.from(getApplicationContext()).inflate(R.layout.start_purchase_ui, null, false);
createPopup(v, this);
getSupportFragmentManager().beginTransaction().replace(R.id.translate_layout, mFragment).commit();
}
I have looked around and seen some suggestions to change getItemCount to not return 0. That did not help and I do not really see how that can be the problem. Here it says for ListViews one must do the restoration in either onCreateView or onActivityCreated, that did not help either.
Note that notifyDataSetChangedis called in addData(Words word)
EDIT: I have changed the flow to the following:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_translate, container, false);
mRecyclerView = root.findViewById(R.id.translate_recycle);
mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayout.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
mAdapter = new CustomAdapter(mRecyclerView, this.getContext(), this);
mRecyclerView.setAdapter(mAdapter);
return root;
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState){
mHelper = new Helper();
if (savedInstanceState == null) {
// Create helper instance
// Get the input view from which we get the source word
textInput = v.findViewById(R.id.source_input);
// Extract the chosen langauges
Intent intent = getActivity().getIntent();
source_lang = intent.getStringExtra(MainActivityFragment.SOURCE_LANG);
target_lang = intent.getStringExtra(MainActivityFragment.TARGET_LANG);
} else {
source_lang = savedInstanceState.getString(MainActivityFragment.SOURCE_LANG);
target_lang = savedInstanceState.getString(MainActivityFragment.TARGET_LANG);
ArrayList<String> w1 = savedInstanceState.getStringArrayList(TranslateActivity.W1LIST);
ArrayList<String> w2 = savedInstanceState.getStringArrayList(W2LIST);
restoreWords(w1,w2);
}
key = mHelper.getKey(source_lang, target_lang);
mTranslater = new Translater(source_lang, target_lang, key);
setHasOptionsMenu(true);
setToolbarText();
}
More Information:
I have an EditText item from which I read the input and add to the mAdapter. After rotation, that does still work. It is only when I try to re-insert the saved data it doesn't work. So I suspect restoreWords are called from the wrong method?
So it seems like the solution was to do the restoration in the Activity instead of the Fragment. I did almost the same exactly as in my question. I overwrote onRestoreInstanceState and called restoreWords implemented as
public void restoreWords(ArrayList<String> w1, ArrayList<String> w2){
System.out.println("..................RESTORE WORDS....................");
for (int i = 0; i < w1.size(); ++i){
Words tmp = new Words(w1.get(i), w2.get(i), 0, 0, 0, false);
System.out.println(tmp.getW1() + " --- " + tmp.getW2());
mFragment.addWordToView(tmp);
}
System.out.println("-------------------Number of words in adapter: " + mFragment.getAdapter().getItemCount());
}
Then it magically worked. Can someone explain why?
Related
I have a RecyclerView, it has items in it. I need each item to have its own Activity, that is, we have item1 by clicking on it, Activity1 opens, there is also item2 about clicking on it, Activity2 is opened. Can this be done somehow? If so, how? I managed to make it so that when I clicked, the same Fragment opened, and the text changes depending on which item was clicked. But it doesn't quite suit me.
Fragment where the RecyclerView is located
public class FragmentAttractionRecyclerView extends Fragment {
private RecyclerView mRec;
private AttractionsAdapter adapter;
private ArrayList<AttractionsItem> exampleList;
private RecyclerView.LayoutManager mLayoutManager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_attraction_test_2, container, false);
}
#SuppressLint("InflateParams")
#Override
public void onViewCreated(#NonNull final View view, #Nullable Bundle savedInstanceState) {
createExampleList();
buildRecyclerView();
}
public void createExampleList() {
exampleList = new ArrayList<>();
exampleList.add(new AttractionsItem(R.mipmap.unnamed, R.drawable.ic_kid, "Baby островок", "Детский", "60₽","Максимальное кол-во детей","10","Возраст","С 1-го до 6 лет"));
exampleList.add(new AttractionsItem(R.mipmap.unnamed, R.drawable.ic_kid, "Виражи", "Детский", "80₽","Максимальное кол-во пассажиров","24", "Возраст","От 4-х до 12 лет"));
exampleList.add(new AttractionsItem(R.mipmap.unnamed, R.drawable.ic_kid, "Вокруг света", "Детский", "50₽","Максимальное кол-во пассажиров","12","Возраст","От 3-х до 12 лет"));
exampleList.add(new AttractionsItem(R.mipmap.unnamed, R.drawable.ic_interactive, "5D кинотеатр", "Интерактивный", "120₽","Максимальное кол-во пассажиров","","Возраст","С 6 лет"));
}
public void buildRecyclerView() {
mRec = requireView().findViewById(R.id.attraction_recycler);
adapter = new AttractionsAdapter(exampleList);
mLayoutManager = new LinearLayoutManager(getContext());
mRec.setLayoutManager(mLayoutManager);
mRec.setAdapter(adapter);
}
}
Adapter for RecyclerView
public class AttractionsAdapter extends RecyclerView.Adapter<AttractionsAdapter.AttractionsViewHolder> {
public ArrayList<AttractionsItem> mFavList;
public AttractionsAdapter(ArrayList<AttractionsItem> favList) {
mFavList = favList;
}
#NonNull
#Override
public AttractionsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_attraction, parent, false);
AttractionsViewHolder evh = new AttractionsViewHolder(v);
return evh;
}
public static class AttractionsViewHolder extends RecyclerView.ViewHolder {
public ImageView card_image_1, card_image_2;
public TextView card_text_1, card_text_2, card_text_3,attraction_menu_1_1,attraction_menu_1_2;
public CardView Card;
public AttractionsViewHolder(View itemView) {
super(itemView);
card_image_1 = itemView.findViewById(R.id.card_image_1);
card_image_2 = itemView.findViewById(R.id.card_image_2);
card_text_1 = itemView.findViewById(R.id.card_text_1);
card_text_2 = itemView.findViewById(R.id.card_text_2);
card_text_3 = itemView.findViewById(R.id.card_text_3);
attraction_menu_1_1 = itemView.findViewById(R.id.attraction_menu_1_1);
attraction_menu_1_2 = itemView.findViewById(R.id.attraction_menu_1_2);
Card = itemView.findViewById(R.id.Card);
}
}
#Override
public void onBindViewHolder(AttractionsViewHolder holder, int position) {
AttractionsItem currentItem = mFavList.get(position);
holder.card_image_1.setImageResource(currentItem.getImg1());
holder.card_image_2.setImageResource(currentItem.getImg2());
holder.card_text_1.setText(currentItem.get_attraction_name());
holder.card_text_2.setText(currentItem.get_attraction_type());
holder.card_text_3.setText(currentItem.get_attraction_cost());
holder.Card.setOnClickListener(v -> {
FragmentBlancAttraction fragment = new FragmentBlancAttraction(); // you fragment
FragmentManager fragmentManager = ((FragmentActivity) v.getContext()).getSupportFragmentManager(); // instantiate your view context
Bundle bundle = new Bundle();
bundle.putString("name", currentItem.get_attraction_name());
bundle.putString("menu_1_1", currentItem.get_attraction_menu_1_1());
bundle.putString("menu_1_2", currentItem.get_attraction_menu_1_2());
bundle.putString("menu_2_1", currentItem.get_attraction_menu_2_1());
bundle.putString("menu_2_2", currentItem.get_attraction_menu_2_2());
fragment.setArguments(bundle);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.animator.nav_default_enter_anim, R.animator.nav_default_exit_anim,
R.animator.nav_default_pop_enter_anim, R.animator.nav_default_pop_exit_anim);
fragmentTransaction.replace(R.id.fragment, fragment);// your container and your fragment
fragmentTransaction.addToBackStack("tag");
fragmentTransaction.commit();
});
}
#Override
public int getItemCount() {
return mFavList.size();
}
}
public class AttractionsItem
{
private int mImg_1,mImg_2;
private final String mText_attraction_name;
private final String mText_attraction_type;
private final String mText_attraction_cost;
private final String mText_attraction_menu_1_1;
private final String mText_attraction_menu_1_2;
private final String mText_attraction_menu_2_1;
private final String mText_attraction_menu_2_2;
public AttractionsItem(int img1,int img2, String text_attraction_name, String text_attraction_type, String text_attraction_cost, String text_attraction_menu_1_1, String text_attraction_menu_1_2, String text_attraction_menu_2_1, String text_attraction_menu_2_2)
{
mImg_1 = img1;
mImg_2 = img2;
mText_attraction_name = text_attraction_name;
mText_attraction_type = text_attraction_type;
mText_attraction_cost = text_attraction_cost;
mText_attraction_menu_1_1 = text_attraction_menu_1_1;
mText_attraction_menu_1_2 = text_attraction_menu_1_2;
mText_attraction_menu_2_1 = text_attraction_menu_2_1;
mText_attraction_menu_2_2 = text_attraction_menu_2_2;
}
public int getImg1()
{
return mImg_1;
}
public int getImg2()
{
return mImg_2;
}
public String get_attraction_name()
{
return mText_attraction_name;
}
public String get_attraction_type()
{
return mText_attraction_type;
}
public String get_attraction_cost()
{
return mText_attraction_cost;
}
public String get_attraction_menu_1_1()
{
return mText_attraction_menu_1_1;
}
public String get_attraction_menu_1_2()
{
return mText_attraction_menu_1_2;
}
public String get_attraction_menu_2_1()
{
return mText_attraction_menu_2_1;
}
public String get_attraction_menu_2_2()
{
return mText_attraction_menu_2_2;
}
}
The positon param inside onBindViewHolder() method tells you which item of your RecyclerView clicked.
Use this to control your program and in out of onBindViewHolder() method you can get your item position by getAdapterPosition().
holder.Card.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (position) {
case 0: {
// Start first activity.
break;
}
case 1: {
// Start Second activity.
break;
}
}
}
});
I have a RecyclerView inside a Fragment within Activity. I need to refresh my RecyclerView from Activity. I added a method inside Fragment which called notifyDatasetChanged to refresh RecyclerView. But notifyDatasetChanged didn't work.
Here is my Fragment.
public class CategoryFragment extends Fragment{
private RecyclerView recyclerView;
private EventsAdapter adapter;
static Context context = null;
private List<Category> categories;
private List<Item> allItems = new ArrayList();
private ReminderDatabase dbHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(!checkDatabase()){
copyDatabase();
}
context = getActivity();
dbHandler = new ReminderDatabase(context);
fillAllItems();
}
public void fillAllItems(){
categories = dbHandler.getAllCategory();
for(int i=0;i<categories.size();i++){
Category category = categories.get(i);
Item categoryItem = new Item(category.getTitle(),category.getColor(),Category.CATEGORY_TYPE);
allItems.add(categoryItem);
List<Event> events = dbHandler.getEventsByCategory(category.getTitle());
for(int j=0;j<events.size();j++){
Event e = events.get(j);
Item eventItem = new Item(e.getId(),e.getTitle(),e.getDescription(),e.getPlace(),e.getCategory(),e.getTime(),e.getDate(),categoryItem.getColor(),e.isShow(),Event.EVENT_TYPE);
allItems.add(eventItem);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.category_fragment, container, false);
recyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);
adapter = new EventsAdapter(getContext(),allItems);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
return v;
}
public boolean checkDatabase(){
String path = "/data/data/com.example.materialdesign.reminder/databases/";
String filename = "Remind";
File file = new File(path+filename);
Log.d("Database","File exists -> "+file.exists());
return file.exists();
}
public void copyDatabase(){
String path = "/data/data/com.example.materialdesign.reminder/databases/Remind";
ReminderDatabase dbHandler = new ReminderDatabase(getContext());
dbHandler.getWritableDatabase();
InputStream fin;
OutputStream fout;
byte[] bytes = new byte[1024];
try {
fin = getActivity().getAssets().open("Remind");
fout = new FileOutputStream(path);
int length=0;
while((length = fin.read(bytes))>0){
fout.write(bytes,0,length);
}
fout.flush();
fout.close();
fin.close();
Log.d("Database","successfully copied database");
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.d("Database","-Error" +e.getMessage());
} catch (IOException e) {
e.printStackTrace();
Log.d("Database","-Error" +e.getMessage());
}
}
#Override
public void onResume() {
super.onResume();
allItems.clear();
Log.d("TAG","onresume");
fillAllItems();
adapter.notifyDataSetChanged();
}
public void refresh(){
Log.d("c",allItems.size()+"");
allItems.clear();
fillAllItems();
Log.d("c",allItems.size()+"");
adapter.notifyDataSetChanged();
}
}
I called refresh method from MainActivity.
#Override
public void onInserted() {
fragment.refresh();
}
My Adapter is here.
public class EventsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private Context context;
private List<Item> allItems = new ArrayList();
private HideOrShowListener hideOrShowListener;
public static final int EVENT_TYPE = 1;
public static final int CATEGORY_TYPE = 0;
private int lastPosition;
private boolean flag = false;
public EventsAdapter(Context context,List<Item> allItems){
this.context = context;
hideOrShowListener =(HideOrShowListener) context;
this.allItems = allItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType){
case CATEGORY_TYPE:
view = LayoutInflater.from(context).inflate(R.layout.category_item,parent,false);
return new CategoryViewHolder(view);
case EVENT_TYPE:
view = LayoutInflater.from(context).inflate(R.layout.events_item,parent,false);
return new EventViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
final Item item = allItems.get(position);
switch (item.getType()){
case CATEGORY_TYPE:
((CategoryViewHolder)holder).tvCategoryTitle.setText(item.getTitle());
((GradientDrawable)(((CategoryViewHolder)holder).categoryColorIcon).getBackground()).setColor(Color.parseColor(item.getColor()));
((CategoryViewHolder)holder).imgAddEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideOrShowListener.setHideOrShow(item,false);
}
});
break;
case EVENT_TYPE:
String[] time = item.getTime().trim().split(":");
int hour = Integer.parseInt(time[0]);
((EventViewHolder)holder).tvEventName.setText(item.getTitle());
((EventViewHolder)holder).tvTime.setText(hour<12?hour+" : "+time[1] +" am" : hour-12+" : "+time[1] +" pm" );
((EventViewHolder)holder).tvPlace.setText(item.getPlace());
if(item.getDescription().length()==0) {
item.setDescription("No Detail");
}
((EventViewHolder)holder).tvDescription.setText(item.getDescription());
if(item.isShow()){
((EventViewHolder)holder).descriptionLayout.animate().alpha(1).setDuration(200).setInterpolator(new AccelerateInterpolator()).start();
((EventViewHolder)holder).descriptionLayout.setVisibility(View.VISIBLE);
((EventViewHolder)holder).descriptionLayout.setSelected(true);
((EventViewHolder)holder).tvEdit.setVisibility(View.VISIBLE);
((EventViewHolder)holder).eventContainer.setSelected(true);
}else{
((EventViewHolder)holder).descriptionLayout.setVisibility(View.GONE);
((EventViewHolder)holder).descriptionLayout.animate().alpha(0).setDuration(500).start();
((EventViewHolder)holder).descriptionLayout.setSelected(false);
((EventViewHolder)holder).eventContainer.setSelected(false);
((EventViewHolder)holder).tvEdit.setVisibility(View.INVISIBLE);
}
((EventViewHolder)holder).tvEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideOrShowListener.setHideOrShow(item,true);
}
});
break;
}
}
#Override
public int getItemCount() {
Log.d("c",allItems.size()+"");
return allItems.size();
}
#Override
public int getItemViewType(int position) {
if(allItems!=null){
return allItems.get(position).getType();
}
return 0;
}
public class CategoryViewHolder extends RecyclerView.ViewHolder{
private TextView tvCategoryTitle;
private View categoryColorIcon;
private ImageView imgAddEvent;
public CategoryViewHolder(View itemView) {
super(itemView);
tvCategoryTitle = (TextView) itemView.findViewById(R.id.tvCategoryTitle);
categoryColorIcon = itemView.findViewById(R.id.categoryColorIcon);
imgAddEvent = (ImageView) itemView.findViewById(R.id.addEvent);
}
}
public class EventViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private LinearLayout descriptionLayout;
private RelativeLayout eventContainer;
private TextView tvEventName,tvTime,tvPlace,tvDescription,tvEdit;
public EventViewHolder(View itemView) {
super(itemView);
descriptionLayout = (LinearLayout) itemView.findViewById(R.id.descriptionLayout);
eventContainer = (RelativeLayout) itemView.findViewById(R.id.eventContainer);
tvEventName = (TextView) itemView.findViewById(R.id.tvEventName);
tvTime = (TextView) itemView.findViewById(R.id.tvTime);
tvPlace = (TextView) itemView.findViewById(R.id.tvPlace);
tvDescription = (TextView) itemView.findViewById(R.id.tvDescription);
tvEdit = (TextView) itemView.findViewById(R.id.tvEdit);
eventContainer.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(flag){
allItems.get(lastPosition).setShow(false);
}
allItems.get(getAdapterPosition()).setShow(true);
flag = true;
lastPosition = getAdapterPosition();
notifyDataSetChanged();
}
}
public interface HideOrShowListener{
public void setHideOrShow(Item item , boolean isEdit);
}
}
But when I click home button and reenter my application, my RecyclerView refresh. It means that notifyDatasetChanged in onResume method works. But in my refresh method, it doesn't work. How can I do this?
Are you sure this method is being called :
#Override
public void onInserted() {
fragment.refresh();
}
Make sure that you've a correct instance of the fragment. Or you can simply user interface with the refresh() method and implement it in the fragment.
I am working on an app that includes shopping feature and items are added to cart.
I have navigation drawer. In that, I have my first fragment called as "POSFragment" in which I have implemented a viewpager as data to be shown in the form of swipeable tabs. The data will be inflated dynamically. So, I have used PagerTabStrip and a viewpager. There is a common fragment called "MenuDetailFragment" in which data will be inflated dynamically through a webservice. the adapter for this fragment is "MenuPagerAdapter". Now, In this fragment the data will shown in listview. In Listview in each row items can be incremented or decremented using plus and minus Buttons in each row. Between these button there is textview where the quantity will be displayed correspondingly. I have used a Linkedhashmap on both buttons so, the items along with the quantity is saved in linkedhashmap and then in Sharedpreferences. It's working fine till now. The issue occurs when I swipe in the View pager and next fragment appears and When I click on increment button or decrement button on item there. In shared preferences, It starts saving the current fragment items and previous fragment data is not there anymore. I have already used the "yourcustomviewpager.setOffscreenPageLimit(3)" So, I can see the selected items with the quantities whe I swipe to and fro but the data i stored in sharedpreferences using Linkedhashmap is not there instead current fragment's data is saved. I want that the new data is added to previous data and data in all the fragments should persist. Is there a way to do so? I have been facing this issue for quite a long time.
Here are some screenshots and relevant code snippet.
public class PosFragment extends Fragment {
private ViewPager viewPager;
View rootview;
String code;
String name;
String desc;
String rate;
String key;
Button viewCartBtn;
static TextView displayPrice;
static TextView noOfItemsInCart;
RippleView rippleView;
//private sendPosition pos;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
Log.e("oncreateview", "called");
// Inflate the layout for this fragment
rootview = inflater.inflate(R.layout.pos_fragment_layout, container, false);
initViews();
new AsyncTaskGetMenu().execute();
return rootview;
}
public void initViews() {
Log.e("init", "called");
viewPager = (ViewPager) rootview.findViewById(R.id.viewPager);
Button viewCartButton = (Button) rootview.findViewById(R.id.view_cart_btn);
viewPager.setOffscreenPageLimit(3);
viewCartBtn = (Button) rootview.findViewById(R.id.view_cart_btn);
AppMethods.setGlametrixBoldFont(getActivity(), viewCartBtn);
displayPrice = (TextView) rootview.findViewById(R.id.textView_totalprice_cart);
noOfItemsInCart = (TextView) rootview.findViewById(R.id.cart_items_quantity);
viewCartBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ViewCartActivity.class);
intent.putExtra(AppConstants.SUBTOTAL, Integer.parseInt(displayPrice.getText().toString()));
startActivity(intent);
}
});
LinearLayout itemsInCartLinearLayout = (LinearLayout) rootview.findViewById(R.id.ll_items_in_cart);
itemsInCartLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), ViewCartActivity.class);
intent.putExtra(AppConstants.SUBTOTAL, Integer.parseInt(displayPrice.getText().toString()));
startActivity(intent);
}
});
}
This is "MenuDetailFragment" class
public class MenuDetailFragment extends Fragment {
View rootview;
private ListView listView;
private ArrayList<MenuHeadingDetailsModel> menuheadingDetailList;
private Communicate comm;
LinkedHashMap<String, ViewCartDetailsModel> viewCartDetailsModelMap = new LinkedHashMap<>();
ViewCartDetailsModel viewCartDetailsModel;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootview = inflater.inflate(R.layout.menu_list, container, false);
InitializeViews();
return rootview;
}
public void InitializeViews() {
listView = (ListView) rootview.findViewById(R.id.menu_items_list);
Bundle bundle = getArguments();
menuheadingDetailList = bundle.getParcelableArrayList(AppConstants.MENU_KEY);
listView.setAdapter(new MenuAdapter(getActivity(), menuheadingDetailList));[enter image description here][1]
This is"MenuPagerAdapter" class
public class MenuPagerAdapter extends FragmentStatePagerAdapter {
List<MenuModel> menu;
public MenuPagerAdapter(FragmentManager fm, List<MenuModel> menuList) {
super(fm);
this.menu = menuList;
}
#Override
public CharSequence getPageTitle(int position) {
return menu.get(position).getHeading().toString();
}
private List<MenuHeadingDetailsModel> getMenuHeadingDetails(int pos) {
return this.menu.get(pos).getMenuHeadingDetailList();
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new MenuDetailFragment();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(AppConstants.MENU_KEY, (ArrayList<? extends Parcelable>) getMenuHeadingDetails(position));
fragment.setArguments(bundle);
return fragment;
}
#Override
public int getCount() {
return menu.size();
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer == null) {
super.unregisterDataSetObserver(observer);
}
}
#Override
public void destroyItem (ViewGroup container, int position, Object object)
{
Log.e("destroyitem","called");
}
}
class MenuAdapter extends BaseAdapter {
//ViewHolder holder;
Context context;
List<MenuHeadingDetailsModel> myItems = new ArrayList<>();
Button buttonPlus, buttonMinus;
int totalAmount = 0;
int pagePosition;
public MenuAdapter(Context context, List<MenuHeadingDetailsModel> myItems) {
this.context = context;
this.myItems = myItems;
}
#Override
public int getCount() {
return myItems.size();
}
#Override
public Object getItem(int position) {
return myItems.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder = new ViewHolder();
final LayoutInflater inflater = getActivity().getLayoutInflater();
convertView = inflater.inflate(R.layout.menu_list_item, null);
viewHolder.codeText = (TextView) convertView.findViewById(R.id.textView_code);
viewHolder.nameText = (TextView) convertView.findViewById(R.id.textView_name);
AppMethods.setGlametrixBoldFont(getActivity(), viewHolder.nameText);
viewHolder.descText = (TextView) convertView.findViewById(R.id.textView_desc);
viewHolder.rateText = (TextView) convertView.findViewById(R.id.textView_rate);
viewHolder.textViewNoOfItems = (TextView) convertView.findViewById(R.id.tv_no_of_items);
buttonMinus = (Button) convertView.findViewById(R.id.button_minus);
buttonPlus = (Button) convertView.findViewById(R.id.button_plus);
final MenuHeadingDetailsModel menu = myItems.get(position);
viewHolder.codeText.setText(menu.getCode());
viewHolder.nameText.setText(menu.getItemName());
viewHolder.descText.setText(menu.getDescription());
viewHolder.rateText.setText(menu.getRate());
viewHolder.textViewNoOfItems.setText("" + menu.getQuantity());
buttonPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MenuHeadingDetailsModel menuList = myItems.get(position);
menuList.setQuantity(menuList.getQuantity() + 1);
myItems.set(position, menuList);
int itemRate = Integer.parseInt(myItems.get(position).getRate());
int itemQuan = menuList.getQuantity();
String code = menuList.getCode();
String name = menuList.getItemName();
int totalAmountPerItem = itemQuan * itemRate;
viewCartDetailsModel = new ViewCartDetailsModel(code, name, itemQuan, itemRate);
viewCartDetailsModelMap.put(viewCartDetailsModel.getCode(), viewCartDetailsModel);
Log.e("hashmap", "size" + viewCartDetailsModelMap.size());
Gson gson = new Gson();
String hashMapToString = gson.toJson(viewCartDetailsModelMap);
AppPreferences.saveDataInSharedpreferences(getActivity(), AppConstants.VIEW_ITEMS_INT_CART_KEY, hashMapToString);
totalAmount += itemRate;
int amount = totalAmount;
onButtonPressedForAmount(amount);
notifyDataSetChanged();
int quan = 0;
TextView tv;
for (int i = 0; i < listView.getCount(); i++) {
View view = listView.getAdapter().getView(i, null, null);
tv = (TextView) view.findViewById(R.id.tv_no_of_items);
quan = quan + Integer.parseInt(tv.getText().toString());
}
onButtonClickedForQuantity(quan);
}
}
);
buttonMinus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MenuHeadingDetailsModel menuList = myItems.get(position);
if ((menuList.getQuantity() - 1) >= 0) {
menuList.setQuantity(menuList.getQuantity() - 1);
myItems.set(position, menuList);
int itemRate = Integer.parseInt(myItems.get(position).getRate());
int itemQuan = menuList.getQuantity();
String code = menuList.getCode();
String name = menuList.getItemName();
//int totalAmountPerItem = itemQuan * itemRate;
viewCartDetailsModel = new ViewCartDetailsModel(code, name, itemQuan, itemRate);
if (itemQuan == 0) {
viewCartDetailsModelMap.remove(code);
} else {
viewCartDetailsModelMap.put(viewCartDetailsModel.getCode(), viewCartDetailsModel);
}
Gson gson = new Gson();
String hashMapToString = gson.toJson(viewCartDetailsModelMap);
AppPreferences.saveDataInSharedpreferences(getActivity(), AppConstants.VIEW_ITEMS_INT_CART_KEY, hashMapToString);
if (totalAmount > 0) {
totalAmount -= itemRate;
Log.e("totalamount", "minus" + totalAmount);
int amount = totalAmount;
onButtonPressedForAmount(amount);
}
} else {
menuList.setQuantity(0);
myItems.set(position, menuList);
}
notifyDataSetChanged();
int quan = 0;
TextView tv;
for (int i = 0; i < listView.getCount(); i++) {
View view = listView.getAdapter().getView(i, null, null);
tv = (TextView) view.findViewById(R.id.tv_no_of_items);
quan = quan + Integer.parseInt(tv.getText().toString());
}
onButtonClickedForQuantity(quan);
}
}
);
return convertView;
}
public void onButtonPressedForAmount(int userData) {
if (comm != null) {
comm.sendAmount(userData);
}
}
public void onButtonClickedForQuantity(int quantity) {
if (comm != null) {
comm.sendQuantity(quantity);
}
}
class ViewHolder {
TextView nameText;
TextView codeText;
TextView descText;
TextView rateText;
TextView textViewNoOfItems;
}
}
//For settings fonts to the alert diaolog for customization of items
//public void setGlametrixBoldFont(TextView textView) {
//Typeface typeface = Typeface.createFromAsset(getActivity().getAssets(), "fonts/GlametrixBold.otf");
//textView.setTypeface(typeface);
// }
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
comm = (Communicate) activity;
} catch (Exception e) {
AppMethods.getStackTrace(e);
}
}
public interface Communicate {
public void sendAmount(int amount);
public void sendQuantity(int quantity);
}
// public void getPosition(int Position) {
//
// int pagePosition = Position;
// Log.e("pos", " " + pagePosition);
// }
}
You can get your current fragment inside view pager by following below way
SampleFragment sampleFr = (SampleFragment) viewPager.getAdapter().instantiateItem(viewPager, 0);
Now you can access any data you want using that fragment.
For the first time adding fragments in view pager do like below way.
BaseFragment frTimeLine = (BaseFragment) Fragment.instantiate(this, SampleFragment.class.getName());
fragments.add(frTimeLine);
BaseFragment frEarnTiqs = (BaseFragment) Fragment.instantiate(this, SampleFragment1.class.getName());
fragments.add(frEarnTiqs);
adapter = new ViewPagerAdapter(getSupportFragmentManager(), getResources(), fragments);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(3);
I am having some trouble with my app, I am trying to develop a list app that you have the option to add new "Goals" to as well as new lists so that you can categorize goals to a list like the list object title can be "Eat healthy" and then you'll have goals inside like "Eat more vegetables", etc. So in order to do this I have set up a ViewPagerHost class that grabs all the List objects from a SQLite database and initializes a factory developed "List fragment" that handles all the logic of adding a goal, editing and deleting, etc. I believe I've gotten this to work correctly because everything on the database side seems to work fine, and then the other classes are just supposed to display and manipulate that information. But everything on the display side seems to be going wrong. I have each view in the recyclerview display a star next to any goal marked as "important" or "life changing" but it displays the star wherever it wants. Also the list does not load until I've click on something.
public class ViewPagerHost extends Activity_Logger {
private static final String ARG_TITLE = "title";
private ViewPager mViewPager;
private ArrayList<Fragment> mFragmentList;
private ArrayList<GoalList> goalList;
private ArrayList<Goal> goalArrayList;
Database_Controller controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_pager_host);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
MobileAds.initialize(getApplicationContext(), "ad-String");
AdView adView = (AdView) findViewById(R.id.ad);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
setSupportActionBar(toolbar);
toolbar.setTitle("Ambition");
FragmentManager fragmentManager = getSupportFragmentManager();
controller = Database_Controller.get(getApplicationContext());
goalList = controller.getAllLists();
goalArrayList = controller.getAllGoals();
mViewPager = (ViewPager)findViewById(R.id.view_fragments);
if(goalList.get(0) == null){
GoalList listOne = new GoalList();
listOne.setTitle("DEFAULT");
controller.insertList(listOne);
for(int i =0; i< goalArrayList.size(); i++){
goalArrayList.get(i).setWhich_List(listOne.getTitle());
controller.updateGoal(goalArrayList.get(i));
}
}
mFragmentList = getFragmentList(goalList);
ViewPagerAdapter adapter = new ViewPagerAdapter(fragmentManager, mFragmentList);
if(adapter == null){
}else{
mViewPager.setAdapter(adapter);
}
}
public ArrayList<Fragment> getFragmentList(ArrayList<GoalList> list){
mFragmentList = new ArrayList<>();
Bundle bundle = new Bundle();
for(int i = 0; i< list.size(); i++){
List_Fragment list_fragment = new List_Fragment();
bundle.putString(ARG_TITLE, goalList.get(i).getTitle());
list_fragment.setArguments(bundle);
mFragmentList.add(list_fragment);
}
return mFragmentList;
}
}
Here is my ViewPagerHost class that creates the factory list.
public class List_Fragment extends Fragment {
private RecyclerView mRecyclerView;
private static final String ARG_TITLE = "title";
private static final String ARG_GOALNAME ="Goal";
private static final String ARG_IMPORTANT = "Important";
private Database_Controller mDatabaseController;
private static final String ARG_ID = "ID";
ArrayList<Goal> goalList;
LinearLayoutManager manager;
public RecyclerView.Adapter adapter;
public ReceiverThread UiThread;
FragmentManager fragmentManager;
String list_title;
public List_Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list_, container, false);
Bundle bundle = getArguments();
if(bundle != null){
list_title= bundle.getString(ARG_TITLE);
}
mDatabaseController = mDatabaseController.get(getContext());
goalList = mDatabaseController.getAllListsGoals(list_title);
mRecyclerView = (RecyclerView)view.findViewById(R.id.recyclerview);
manager = new LinearLayoutManager(getActivity());
UiThread = new ReceiverThread();
mRecyclerView.setLayoutManager(manager);
final RecyclerView_Adapter wrapperClass = new RecyclerView_Adapter(goalList,getContext(),this);
adapter = wrapperClass.adapter;
for(int counter =0; counter < goalList.size(); counter++){
System.out.println(goalList.get(counter).getWhich_List());
}
mRecyclerView.setAdapter(adapter);
fragmentManager= getFragmentManager();
//adapter goes here
final FloatingActionButton fab = (FloatingActionButton)view.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment fragment = List_Fragment.this;
AddNew_PopUp popUp = AddNew_PopUp.newInstance(fragment);
popUp.setTargetFragment(fragment, 0);
popUp.show(fragmentManager, "PopUpDialog");
}
});
return view;
}
public class ReceiverThread extends Thread {
#Override
public void run() {
super.run();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
goalList.clear();
ArrayList<Goal>newGoalList = mDatabaseController.getAllGoals();
goalList.addAll(newGoalList);
adapter.notifyDataSetChanged();
}
});
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 0){
if(resultCode == Activity.RESULT_OK){
Goal newGoal = new Goal();
String GoalName = data.getStringExtra(ARG_GOALNAME);
if (GoalName.isEmpty()) {
Toast.makeText(getContext(), R.string.NoGoal, Toast.LENGTH_SHORT).show();
} else {
newGoal.setmIsImportant(data.getBooleanExtra(ARG_IMPORTANT, false));
newGoal.setmGoalName(GoalName);
newGoal.setWhich_List(ARG_TITLE);
mDatabaseController.insertGoal(newGoal);
}
}
}else{
if(requestCode == 1){
if(resultCode == Activity.RESULT_OK){
String id = data.getStringExtra(ARG_ID);
Toast.makeText(getContext(),R.string.flush, Toast.LENGTH_LONG).show();
mDatabaseController.deleteGoal(id);
}
}else{
if(requestCode == 2){
if(resultCode == Activity.RESULT_OK){
String goalName = data.getStringExtra(ARG_GOALNAME);
Boolean isImportant = data.getBooleanExtra(ARG_IMPORTANT, false);
UUID id = UUID.fromString(data.getStringExtra(ARG_ID));
Goal goal = mDatabaseController.getGoal(id.toString());
goal.setmIsImportant(isImportant);
goal.setmGoalName(goalName);
mDatabaseController.updateGoal(goal);
}
}
}
}
UiThread.run();
}
public ReceiverThread getUiThread() {
return UiThread;
}
}
This is the list fragment that is created for every list in the database. It calls methods and manipulates data based off the user's actions.
public class RecyclerView_Adapter{
private ArrayList<Goal> mGoals;
MyAdapter adapter;
Context context;
private Database_Controller mDatabaseController;
MediaPlayer mediaPlayer;
Fragment fragment;
public RecyclerView_Adapter(ArrayList<Goal> goals, Context cntxt, Fragment fragments) {
mGoals = goals;
adapter = new MyAdapter(mGoals);
context = cntxt;
mediaPlayer = new MediaPlayer();
fragment = fragments;
mDatabaseController = Database_Controller.get(context);
}
//////////////////////////////////ADAPTER\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
private class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private List<Goal> mGoals;
public MyAdapter(List<Goal> goals) {
mGoals = goals;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.recycler_view_item_layout, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Goal goal = mGoals.get(position);
holder.bindGoal(goal);
}
#Override
public int getItemCount() {
return mGoals.size();
}
}
////////////////////////////////////ADAPTER\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
///////////////////////////////////VIEW HOLDER\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mTextView, importantTXT;
private CheckBox mCheckBox;
private Goal mGoal;
private ImageView imgView;
public MyViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AppCompatActivity context = (AppCompatActivity) v.getContext();
FragmentManager manager = context.getSupportFragmentManager();
Edit_PopUp dialog = Edit_PopUp.newInstance(mGoal);
dialog.setTargetFragment(fragment, 2);
dialog.show(manager, "EditDialog");
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//Add delete thingy
AppCompatActivity context = (AppCompatActivity) v.getContext();
FragmentManager manager = context.getSupportFragmentManager();
MoreOptions_PopUp dialog = MoreOptions_PopUp.newInstance(mGoal);
dialog.setTargetFragment(fragment, 1);
dialog.show(manager, "GoalDialog");
return true;
}
});
mTextView = (TextView) itemView.findViewById(R.id.text);
mCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox);
imgView = (ImageView) itemView.findViewById(R.id.imageView);
importantTXT = (TextView) itemView.findViewById(R.id.Important_textView);
mCheckBox.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
mGoal.setFinished(mCheckBox.isChecked());
mDatabaseController.updateGoal(mGoal);
if (mCheckBox.isChecked() == true) {
boolean value = checkWinning(mGoals,context);
PlaySound(value, mGoal.ismIsImportant(), v);
}
}
});
}
public void bindGoal(Goal goal) {
mGoal = goal;
mCheckBox.setChecked(mGoal.isFinished());
mTextView.setText(mGoal.getmGoalName());
if (mGoal.ismIsImportant()) {
imgView.setImageResource(R.mipmap.ic_stars_pressed);
importantTXT.setText(R.string.isImportant);
}
}
public boolean checkWinning(ArrayList<Goal> goals, Context context) {
for (int i = 0; i < goals.size(); i++) {
if (goals.get(i).isFinished() == false) {
return false;
}
}
return true;
}
public void PlaySound(Boolean winningSound, boolean isImportant, View view) {
if(winningSound){
mediaPlayer = MediaPlayer.create(context,R.raw.victory);
Snackbar snackbar = Snackbar.make(view, R.string.completion, Snackbar.LENGTH_LONG);
snackbar.show();
mediaPlayer.start();
}else {
if (isImportant) {
mediaPlayer = MediaPlayer.create(context, R.raw.collect);
mediaPlayer.start();
Snackbar snackbar = Snackbar.make(view, R.string.congrats, Snackbar.LENGTH_SHORT);
snackbar.show();
} else {
mediaPlayer = MediaPlayer.create(context, R.raw.success);
Snackbar snackbar = Snackbar.make(view, R.string.lessCongrats, Snackbar.LENGTH_SHORT);
snackbar.show();
mediaPlayer.start();
}
}
}
}
////////////////////////////////////VIEW HOLDER\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
public MyAdapter getAdapter() {
return adapter;
}
public Fragment getFragment() {
return fragment;
}
}
Here is my adapter class that plays sounds OnClick and binds the view to the Recyclerview.
Any help would be greatly appreciated!
The problem with the stars displayed in every row will be caused because you might be setting them when needed but not hiding them when not needed.
You will have to implement something like this in the getView() method of your adapter.
ImageView starView = (ImageView) v.findViewById(R.id.starView);
starView.setVisibility(goals.get(position).isSpecial() ? View.Visible : View.Gone);
I've got problem with my ListView. I'm creating new object and add it to the database by clicking button in the first fragment. In the second fragment I've got listview with objects from my database. Everything works fine but listView in the second fragment doesn't refresh - I see new objects only after restarting app. All solutions like : notifyDataSetChanged don't work :/
Here's my adapter from first fragment:
public class ConcertAdapter extendsRecyclerView.Adapter<ConcertAdapter.MyViewHolder> {
private static final String FRAGMENT_TAG = "fragmentTag";
private static final String TAG = ConcertAdapter.class.getSimpleName() ;
private LayoutInflater inflater;
private Context context;
private List<Concert> concertList = new ArrayList<>();
private DatabaseHelper mDatabaseHelper = null;
private int selectedRecordPosition = -1;
private MainActivity mActivity;
public ConcertAdapter(Context context, List<Concert> concerts, MainActivity mainActivity) {
this.inflater = LayoutInflater.from(context);
this.concertList = concerts;
this.context = context;
this.mActivity = mainActivity;
}
public void setListConcert(ArrayList<Concert> concertList) {
this.concertList = concertList;
notifyItemRangeChanged(0, concertList.size());
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.from(parent.getContext()).inflate(R.layout.concert_item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final float screenWidthPx = holder.itemView.getResources().getDisplayMetrics().widthPixels;
Concert current = concertList.get(position);
Log.d("mLog", current.getUrl());
holder.mImage.setImageUrl(current.getUrl(), MySingleton.getInstance().getImageLoader());
holder.mImage.getLayoutParams().height = (int) (screenWidthPx * 0.50);
holder.mFav_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked) {
final Concert favConcert = new Concert();
favConcert.setTitle(concertList.get(position).getTitle());
favConcert.setContent(concertList.get(position).getContent());
favConcert.setDate(concertList.get(position).getDate());
favConcert.setUrl(concertList.get(position).getUrl());
try {
final Dao<Concert, Integer> concertDao = getHelper().getConcertDao();
concertDao.create(favConcert);
}catch (SQLException e) {
e.printStackTrace();
}
}
}
});
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date concertDate = new Date();
try {
concertDate = format.parse(current.getDate());
} catch (ParseException e) {
e.printStackTrace();
}
DateTime dt = new DateTime();
DateTime currentDate = dt.withZone(DateTimeZone.forID("Europe/Warsaw"));
int days = Days.daysBetween(new DateTime(currentDate), new DateTime(concertDate)).getDays();
String s = String.valueOf(days);
holder.mDate_btn.setText(s + " dni");
if (s.equals("0")) {
holder.mDate_btn.setText("dziś :)");
}
}
#Override
public int getItemCount() {
return concertList.size();
}
public void setConcerts(List<Concert> concerts) {
concertList = new ArrayList<>(concerts);
}
public void showDisplay(int position) {
Bundle bundle = new Bundle();
bundle.putInt("position", position);
bundle.putString("content", concertList.get(position).getContent());
bundle.putString("date", concertList.get(position).getDate());
bundle.putString("url", concertList.get(position).getUrl());
bundle.putString("title", concertList.get(position).getTitle());
Fragment fragment = new DisplayConcertFragment();
fragment.setArguments(bundle);
mActivity.replaceFragment(fragment);
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public NetworkImageView mImage;
public Button mDate_btn;
public TextView mBubble;
public ToggleButton mFav_btn;
public ImageView mBubbleImage;
private ConcertFragment mConcertFragment;
public MyViewHolder(View itemView) {
super(itemView);
mImage = (NetworkImageView) itemView.findViewById(R.id.concerts_niv);
mDate_btn = (Button) itemView.findViewById(R.id.date_btn);
mImage.setOnClickListener(this);
mFav_btn = (ToggleButton) itemView.findViewById(R.id.fav_btn);
}
#Override
public void onClick(View v) {
showDisplay(getAdapterPosition());
//ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
Toast.makeText(context, "TEST", Toast.LENGTH_LONG).show();
}
public Concert removeItem(int position) {
final Concert concert = concertList.remove(position);
notifyItemRemoved(position);
return concert;
}
}
private DatabaseHelper getHelper() {
if (mDatabaseHelper == null) {
mDatabaseHelper = OpenHelperManager.getHelper(context,DatabaseHelper.class);
}
return mDatabaseHelper;
}
Here's my second adapter:
public class FavAdapter extends ArrayAdapter {
private LayoutInflater mInflater;
private List mRecords;
private Dao<Concert, Integer> concertDao;
private Button mDateButton;
private NetworkImageView mImage;
public FavAdapter(Context context, int resource, List objects, Dao<Concert, Integer> concertDao) {
super(context, resource, objects);
this.mRecords = objects;
this.concertDao = concertDao;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = mInflater.inflate(R.layout.concert_item, parent, false);
if(mRecords.get(position).getClass().isInstance(new Concert())){
final Concert concert = (Concert) mRecords.get(position);
mImage =((NetworkImageView)convertView.findViewById(R.id.concerts_niv));
mImage.setImageUrl(concert.getUrl(), MySingleton.getInstance().getImageLoader());
final float screenWidthPx = mImage.getResources().getDisplayMetrics().widthPixels;
mImage.getLayoutParams().height = (int) (screenWidthPx * 0.50);
mDateButton = (Button) convertView.findViewById(R.id.date_btn);
Date concertDate = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
concertDate = format.parse(concert.getDate());
} catch (ParseException e) {
e.printStackTrace();
}
DateTime dt = new DateTime();
DateTime currentDate = dt.withZone(DateTimeZone.forID("Europe/Warsaw"));
int days = Days.daysBetween(new DateTime(currentDate), new DateTime(concertDate)).getDays();
String s = String.valueOf(days);
mDateButton.setText(s + " dni");
if (s.equals("0")) {
mDateButton.setText("dziś :)");
}
// ((TextView)convertView.findViewById(R.id.teacher_tv)).setText(studentDetails.teacher.teacherName);
}
return convertView;
}
}
And here's my second fragment with ListView:
public class FavFragment extends Fragment {
private static final String TAG = FavFragment.class.getSimpleName() ;
private DatabaseHelper mDatabaseHelper = null;
private ListView mListView;
private int selectedRecordPosition = -1;
private Dao<Concert, Integer> concertDao;
private List<Concert> concertList;
private MainActivity mActivity;
#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.fragment_fav_layout, container, false);
mListView = (ListView)v.findViewById(R.id.concerts_lv);
mActivity = (MainActivity) getContext();
try {
concertDao = getHelper().getConcertDao();
concertList = concertDao.queryForAll();
FavAdapter adapter = new FavAdapter(getContext(), R.layout.concert_item, concertList, concertDao);
mListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
mListView.invalidateViews();
mListView.refreshDrawableState();
} catch (SQLException e) {
e.printStackTrace();
}
Log.e(TAG, "onCreateView notify");
return v;
}
private DatabaseHelper getHelper() {
if (mDatabaseHelper == null) {
mDatabaseHelper = OpenHelperManager.getHelper(getContext(), DatabaseHelper.class);
}
return mDatabaseHelper;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mDatabaseHelper != null) {
OpenHelperManager.releaseHelper();
mDatabaseHelper = null;
}
}
}
Here's my first fragment
public class ConcertFragment extends Fragment implements MyBackPressed {
private static final String FRAGMENT_TAG = "fragmentTag";
private static final String TAG = ConcertFragment.class.getSimpleName() ;
public ProgressBar progress;
private ConcertLoader concertLoader;
private RecyclerView recyclerView;
private Context mContext;
private android.support.v4.app.FragmentManager mFragmentManager;
private MainActivity mActivity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
JodaTimeAndroid.init(getContext());
View v = inflater.inflate(R.layout.fragment_concert_layout, container, false);
progress = (ProgressBar) v.findViewById(R.id.progressBar);
recyclerView = (RecyclerView) v.findViewById(R.id.concerts_rv);
concertLoader = new ConcertLoader(ConcertFragment.this);
mActivity = (MainActivity) getContext();
futureConcerts();
return v;
}
public void futureConcerts() {
concertLoader.execute();
getActivity().getWindow().getDecorView().getRootView().setClickable(false);
}
public void notifyAboutListCreation(List<Concert> res) {
ConcertAdapter adapter = new ConcertAdapter(getActivity().getApplicationContext(), res, mActivity);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
progress.setVisibility(View.GONE);
adapter.notifyDataSetChanged();
}
#Override
public void onBackPressed() {
getActivity().finish();
}
}
I had similar problems a while ago. Are you triggering any UI updates from non-UI threads? Maybe from within listeners? Try using the following code where the UI updates are triggered.
runOnUiThread(new Runnable(){
#Override
public void run(){
...
adapter.notifyDataSetChanged();
mListView.invalidateViews();
mListView.refreshDrawableState();
...
}
});
Personally, I now have started to wrap any problematic code blocks in a generic try-catch block that catches Exception and see if there are any exceptions I migh thave overseen (using logcat on terminal with tag filter).
(Cannot comment yet, so answering in this way)