RecyclerView notifyDatasetChanged not working - android

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.

Related

RecyclerView filled with Objects from SharedPreferences is slow and laggy

I am building an app which has a RecyclerView which holds Objects that are retrieved from SharedPreferences.
Unfortunately the RecyclerView is lagging when it is binded.
This is my Adapter
public class ShiftAdapter extends RecyclerView.Adapter<ShiftAdapter.ViewHolder>{
private List<Shift> mDataSet;
private Context mContext;
private static final String TAG = "ShiftAdapter";
public int previousExpandedPosition = -1;
public int mExpandedPosition = -1;
private static SharedPreferences mPrefs;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Boolean isStart;
private Date shiftIn;
private Date shiftOut;
private Date mDate;
public EditText mshiftInText;
public EditText mshiftOutText;
public Date date;
public ShiftAdapter(Context context, List<Shift> list) {
mDataSet = list;
mContext = context;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mDate;
public TextView mTime;
public TextView mPay;
public RelativeLayout mRelativeLayout;
public LinearLayout mExepandableLayout;
public Date mshiftIn;
public Date mshiftOut;
public EditText mshiftInText;
public EditText mshiftOutText;
public Button mUpdateButton;
public Button mDeleteButton;
public ViewHolder(View v) {
super(v);
mDate = (TextView) v.findViewById(R.id.date_TV);
mTime = (TextView) v.findViewById(R.id.time_TV);
mPay = (TextView) v.findViewById(R.id.pay_TV);
mRelativeLayout = (RelativeLayout) v.findViewById(R.id.rel_layout);
mExepandableLayout = (LinearLayout) v.findViewById(R.id.expandableLayout);
mshiftInText = (EditText) v.findViewById(R.id.setShiftIn);
mshiftOutText = (EditText) v.findViewById(R.id.setShiftOut);
mUpdateButton = (Button) v.findViewById(R.id.updateButton);
mDeleteButton = (Button) v.findViewById(R.id.deleteButton);
}
}
#Override
public ShiftAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.shift, parent, false);
ViewHolder vh = new ViewHolder(itemView);
return vh;
}
//TODO:Bind all the view elements to Shift Properties
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int i) {
// Format double
String hours = new DecimalFormat("##.##").format(mDataSet.get(i).getHours());
String pay = new DecimalFormat("##.##").format(mDataSet.get(i).getPay());
//set the Text
holder.mTime.setText(hours);
holder.mDate.setText(mDataSet.get(i).dateToString());
holder.mPay.setText(pay);
Log.d(TAG, "onBindViewHolder: called");
// new AsyncTask<>().ex
//Expand mExapndableLayout
final int position = i;
final boolean isExpanded = position ==mExpandedPosition;
holder.mExepandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
// //set shift Times
// shiftIn = mDataSet.get(position).getInDate();
// shiftOut = mDataSet.get(position).getInDate();
if (isExpanded)
previousExpandedPosition = position;
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mExpandedPosition = isExpanded ? -1:position;
notifyItemChanged(previousExpandedPosition);
notifyItemChanged(position);
}
});
//fill expandable layout
holder.mshiftInText.setText(mDataSet.get(position).fullTimeToString(0));
final EditText in = holder.mshiftInText;
final EditText out = holder.mshiftOutText;
//edit mShiftIn Text
holder.mshiftInText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =true;
timePickerDialog(in,out);
}
});
holder.mshiftOutText.setText(mDataSet.get(position).fullTimeToString(1));
//edit MshiftOut Text
holder.mshiftOutText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =false;
timePickerDialog(in,out);
}
});
//updateButton onClick
holder.mUpdateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
shiftIn = mDataSet.get(position).getInDate();
shiftOut = mDataSet.get(position).getOutDate();
if(Validate.getValidate().isDateValid(shiftIn,shiftOut)) {
SharedPrefs.getInstance(mContext).editShift(newShift(shiftIn, shiftOut),Integer.toString(position));
int length = SharedPrefs.getInstance(mContext).getLength() - 1;
if (SharedPrefs.getInstance(mContext).getShift(length) != null) {
Log.d(TAG, "Edit Shift onClick: Success");
SharedPrefs.getInstance(mContext).saveShiftList(SharedPrefs.getInstance(mContext).sortList(SharedPrefs.getInstance(mContext).getShiftList()));
ShiftsFragment.updateUI();
Toast.makeText(mContext, "success", Toast.LENGTH_SHORT).show();
}
} else {
mShiftOut.setBackgroundResource(R.drawable.red_border);
Toast.makeText(mContext, "error", Toast.LENGTH_SHORT).show(); }
} catch(Exception e){
Log.d(TAG, "onDateSelected: "+e.toString());
Toast.makeText(mContext,"update FAIL", Toast.LENGTH_SHORT).show();
}
// update the Shift
}
});
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
areYouSure(mExpandedPosition);
}
});
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public Date timePickerDialog(EditText in,EditText out) {
mshiftInText = in;
mshiftOutText = out;
new SingleDateAndTimePickerDialog.Builder(mContext)
.title(mContext.getResources().getString(R.string.choose_time))
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
#Override
public void onDisplayed(SingleDateAndTimePicker picker) {
if(!isStart) {
date = mDate;
}
}
}).defaultDate(returnDate(date))
.listener(new SingleDateAndTimePickerDialog.Listener() {
#Override
public void onDateSelected(Date date) {
mDate = date;
if (isStart) {
updateShiftIn(mDate);
mshiftInText.setText(dateToString(mDate));
} else {
updateShiftOut(mDate);
mshiftOutText.setText(dateToString(mDate));
}
}
}).display();
return mDate;
}
public String dateToString(Date date)
{
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String string = df.format(date);
return string;
}
private void updateShiftIn(Date date) {
shiftIn = date;
}
private void updateShiftOut(Date date) {
shiftOut = date;
}
private Date returnDate(Date date)
{
if(date!=null)
{
return date;
}
else return mDate;
}
private void areYouSure(int i)
{
final String position = Integer.toString(i);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
Log.d(TAG, "onClick: isSure=true;");
SharedPrefs.getInstance(mContext).removeShift(position);
ShiftsFragment.updateUI();
case DialogInterface.BUTTON_NEGATIVE:
Log.d(TAG, "onClick: isSure= false");
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(mContext.getResources().getString(R.string.are_you_sure)).setPositiveButton(mContext.getResources().getString(R.string.confirm), dialogClickListener)
.setNegativeButton(mContext.getResources().getString(R.string.cancel), dialogClickListener).show();
}
private Shift newShift(Date start,Date stop)
{
int id = SharedPrefs.getInstance(mContext).getLength();
Shift shift = new Shift(dateToCalendar(start),dateToCalendar(stop),id);
return shift;
}
and this is the Fragment that has the RecyclerView
public class ShiftsFragment extends Fragment {
private Toolbar mToolbar;
private TimePicker timePicker1;
private List<Shift> shiftList = new ArrayList<>();
private RecyclerView recyclerView;
private RelativeLayout relativeLayout;
private RecyclerView.LayoutManager layoutManager;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Context mContext;
private ShiftAdapter mAdapter;
private MenuItem mAdd;
private Menu optionsMenu;
private LinearLayout mShiftAddLL;
private SharedPreferences mPrefs;
private static FragmentManager mFragmentManager;
private static final String TAG = "ShiftsFragment";
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG,"Clicked");
final View view = inflater.inflate(R.layout.shifts_layout,container,false);
mToolbar = view.findViewById(R.id.topbar);
mToolbar.inflateMenu(R.menu.toolbarmenu);
mShiftAddLL = view.findViewById(R.id.add_shiftLayout);
mAdd = mToolbar.getMenu().getItem(0);
timePicker1 = (TimePicker) view.findViewById(R.id.timePicker);
mFragmentManager = getFragmentManager();
//TODO:Add a summary bar on the bottom.
//get the context
mContext = getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.shift_list);
// Define a layout for RecyclerView
layoutManager = new GridLayoutManager(mContext,1);
recyclerView.setLayoutManager(layoutManager);
// Initialize a new Shift array
List<Shift> shiftList = initShifts();
Log.d(TAG,"shift array initiated");
// Initialize an array list from array
// Initialize a new instance of RecyclerView Adapter instance
mAdapter = new ShiftAdapter(mContext,shiftList);
// Set the adapter for RecyclerView
recyclerView.setAdapter(mAdapter);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
//Menu add button onClick
//Opens Add_Shift_Fragment
mAdd.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Fragment selectedFragment = new Add_Shift_Fragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return false;
}
});
return view;
}
//Initializes the Shift list from SharedPreferences and returns it.
private List<Shift> initShifts() {
return SharedPrefs.getInstance(mContext).getShiftList();
}
public static void updateUI()
{
Fragment selectedFragment = new ShiftsFragment();
mFragmentManager.beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
}
}
Everytime i launch the ShiftsFragment there are some frame skips, and the scrolling is choppy and laggy.
Maybe my SharedPreferences handling is what is slowing things down?
public class SharedPrefs {
private static SharedPrefs mSharedPrefs;
private SharedPreferences mPrefs;
private SharedPreferences.Editor mPrefsEditor;
protected Context mContext;
public static final String ID = "shiftList";
private SharedPrefs(Context context) {
mContext = context;
mPrefs = context.getSharedPreferences(ID, Context.MODE_PRIVATE);
mPrefsEditor = mPrefs.edit();
}
public static SharedPrefs getInstance(Context context) {
if (mSharedPrefs == null) {
mSharedPrefs = new SharedPrefs(context.getApplicationContext());
}
return mSharedPrefs;
}
public void saveShiftList(List<Shift> shiftList) {
Gson gson = new Gson();
String json = gson.toJson(shiftList);
mPrefsEditor.putString(ID, json);
mPrefsEditor.apply();
}
public void addShift (Shift shift)
{
List<Shift> shiftList= getShiftList();
shiftList.add(shift);
saveShiftList(shiftList);
}
//Replaced the shift#id with shift
public void editShift(Shift shift,String id)
{
removeShift(id);
addShift(shift);
}
public void removeShift(String id) {
List<Shift> shiftList = getShiftList();
int pos = Integer.parseInt(id);
shiftList.remove(pos);
saveShiftList(shiftList);
}
public void removeShift(int id) {
List<Shift> shiftList = getShiftList();
shiftList.remove(id);
saveShiftList(shiftList);
}
public Shift getShift(int id) {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
Shift shift = shiftList.get(id);
return shift;
}
public List<Shift> getShiftList() {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
if (shiftList!=null) {
return shiftList;
} else{
shiftList = new ArrayList<>();
return shiftList;
}
}
public List<Shift> sortList(List<Shift> shiftList)
{
Collections.sort(shiftList, new Comparator<Shift>() {
public int compare(Shift shift1, Shift shift2) {
if (shift1.getShiftStart() == null || shift2.getShiftStart() == null)
return 0;
return shift1.getShiftStart().compareTo(shift2.getShiftStart());
}
});
return shiftList;
}
public int getLength()
{
return getShiftList().size();
}
}
I have only found this problem with image loading, not just Strings from Object from SharedPrefs.

Transferring data into a separate ArrayList and displaying in RecyclerView

I have two ArrayLists from which I am trying to insert data into separate static ArrayList in another class and display in RecyclerView, but the recycler is not getting populated though the same was being done with a dummy ArrayList.Please help me with this problem.
My Class where I am inserting data from phoneContactNos and phoneContactName in two separate ArrayList: Common.selectedContactNos and Common.selectedContactName.
public void displayMatchedContacts()
{
try {
for (int i = 1; i < phoneContactNos.size(); i++) {
if (phoneContactNos.contains(registeredContactNos.get(i))) {
if (registeredContactNos.get(i) != null) {
try {
indexOfRegNumber = phoneContactNos.indexOf(registeredContactNos.get(i));
//Common.indexPosition_contacts=indexOfRegNumber;
Toast.makeText(this, "index" + String.valueOf(indexOfRegNumber), Toast.LENGTH_LONG).show();
if ((phoneContactNos.get(indexOfRegNumber) != null) &&(phoneContactName.get(indexOfRegNumber) != null)) {
//String regName="";
//String regContact="";
Common.selectedContactNos.add(phoneContactNos.get(indexOfRegNumber));
//Toast.makeText(this,selectedContactNos.get(i).toString(),Toast.LENGTH_SHORT).show();
//Toast.makeText(this,phoneContactNos.get(indexOfRegNumber).toString(),Toast.LENGTH_SHORT).show();
Common.selectedContactName.add(phoneContactName.get(indexOfRegNumber));
//Toast.makeText(this,selectedContactName.get(i).toString(),Toast.LENGTH_SHORT).show();
//Toast.makeText(this, phoneContactName.get(indexOfRegNumber).toString(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "null index no", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.i("Contacts display error", e.getLocalizedMessage());
e.printStackTrace();
}
}
}
}
}catch (Exception e)
{
Log.i("Contacts error in loop", e.getLocalizedMessage());
e.printStackTrace();
}
}
My Common class
public final class Common {
public static ArrayList<String> selectedContactNos=new ArrayList<>();
public static ArrayList<String> selectedContactName=new ArrayList<>();
public static String fcmId="";
public static int position;
public static String contacts_list="";
public static int indexPosition_contacts;
}
My RecyclerView populating code
public void populateList() {
Log.i("Populate List","Entered");
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
recyclerView_contacts.setLayoutManager(mLinearLayoutManager);
displayRecyclerAdapter = new DisplayRecyclerAdapter(this);
recyclerView_contacts.setAdapter(displayRecyclerAdapter);
}
My Adapter Class
public class DisplayRecyclerAdapter extends RecyclerView.Adapter<DisplayRecyclerAdapter.displayViewHolder> {
private LayoutInflater mInflater;
private Context context;
Fragment fragment;
FragmentTransaction ft;
FrameLayout container;
public DisplayContacts displayContacts;
public DisplayRecyclerAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
this.context = context;
ft = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
//displayContacts = new DisplayContacts();
}
#Override
public displayViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.contacts_row, parent, false);
displayViewHolder holder = new displayViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(displayViewHolder holder, int position) {
holder.setData(position);
//Common.position = position;
holder.setListeners();
//for(int i=0;i<((DisplayContacts)context).selectedContactName.size();i++)
for(int i=0;i<Common.selectedContactName.size();i++)
{
//String contactName=((DisplayContacts)context).selectedContactName.get(i);
String contactName=Common.selectedContactName.get(i);
//String contactNumber=((DisplayContacts)context).selectedContactNos.get(i);
String contactNumber=Common.selectedContactNos.get(i);
Toast.makeText(context,contactName+","+contactNumber,Toast.LENGTH_SHORT).show();
}
}
class displayViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
int position;
//ImageView productSearchImg;
TextView name_contactList;
Button call_contact;
public displayViewHolder(View itemView) {
super(itemView);
name_contactList = (TextView) itemView.findViewById(R.id.contactlist_name);
call_contact = (Button) itemView.findViewById(R.id.contactlist_call);
}
public void setData(int position) {
this.position = position;
//String displayContacts=((DisplayContacts) context).selectedContactName.get(position);
String displayContacts=Common.selectedContactName.get(position);
Toast.makeText(context,"name to display"+ displayContacts,Toast.LENGTH_SHORT).show();
//name_contactList.setText(((DisplayContacts) context).selectedContactName.get(position));
//name_contactList.setText(displayContacts);
name_contactList.setText("dummy text");
}
#Override
public void onClick(View v) {
//sendPushNotification();
startAudioCall();
}
public void setListeners() {
call_contact.setOnClickListener(displayViewHolder.this);
}
}
public void startAudioCall() {
Intent i = new Intent(context, AudioCallActivity.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
#Override
public int getItemCount() {
return ((DisplayContacts) context).selectedContactName.size();
}
}
can be one of two things:
1.you are not attaching the adapter with data,hence empty
2.or you are updating your data but not calling notifyDataSetChanged()
try to pass the list data in your Adapter class while you are creating it,then attach it to the recyelerview.
//to give a vary basic example
List dataList;
RvAdapter(Context c,List data){
this.dataList=data;
}
onBidViewHolder(Viewholder holder,int position){
holder.tvName.setText(dataList.get(position).getName());
.......
}
//in your activity/fragment
RvAdapter adapter=new RavAdapter(context,dataList);
recylerview.setAdapter(adapter);
//if you change your data
adapter.notifyDataSetChanged()

How to access a list in a hosting Activity from an external AlertDialog

I have a recyclerView with a list of Competitor objects. The list that populates the RecyclerView is a global Singleton. In that Singleton's constructor I open a Json file, parse it's contents to populate the global Singleton's list of Competitors and use that list to pass to the RecyclerView's adapter. Each list item has an ImageButton. This is what I'm trying to accomplish;
When the user clicks on the ImageButton (Delete Button) I want an AlertDialog to pop up and ask the user if they are sure they want to delete the Competitor. This part I have so far. But what I need to do next I can't figure out. I am able to update the json file that contains the global list's information but I also want to update the recyclerview by removing the Competitor from the RecyclerView by calling:
mCompetitorsList.remove(competitor); notifyItemRemoved(position);
However I can't get a reference to the mCompetitorsList variable from an external Dialog class. The same goes for calling notifiyItemRemoved(position)
What should I do? Below is the code for my Dialog class, my Activity that contains the RecyclerView and it's Adapter as well as the Singleton implementation.
public class MasterCompetitorsListActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private static final String DIALOG_DELETE_COMPETITOR = "DIALOG_DELETE_COMPETITOR";
private RecyclerView mRecyclerView;
private List<Competitor> mCompetitorsList;
private CompetitorListAdapter mAdapter;
private SearchView mSearchView;
private FloatingActionButton mAddCompetitorButton;
private Button mDeletCompetitor;
private TextView mCompetitorHidden;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_master_competitors_list);
mSearchView = (SearchView) findViewById(R.id.searchView);
mSearchView.setOnQueryTextListener(this);
/* initialize the Global Competitor's List for the recyclerview. Because this is a singleton
it should initialize the list for the entire app's runtime
*/
GlobalCompetitorsList.get();
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
mRecyclerView = (RecyclerView) findViewById(R.id.master_competitors_recycler);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mAdapter = new CompetitorListAdapter(this, mCompetitorsList);
mRecyclerView.setAdapter(mAdapter);
// set a separator for the list items
DividerItemDecoration divider = new DividerItemDecoration(
mRecyclerView.getContext(),
layoutManager.getOrientation());
divider.setDrawable(ContextCompat.getDrawable(MasterCompetitorsListActivity.this, R.drawable.divider_dark));
mRecyclerView.addItemDecoration(divider);
mRecyclerView.setAdapter(mAdapter);
mAddCompetitorButton = (FloatingActionButton) findViewById(R.id.add_master_competitor_floating_button);
mAddCompetitorButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MasterCompetitorsListActivity.this, AddNewMasterCompetitorActivity.class);
startActivity(intent);
}
});
}
#Override
public boolean onQueryTextSubmit(String query) {
mCompetitorsList = new ArrayList<>();
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
mAdapter.notifyDataSetChanged();
return false;
}
#Override
public boolean onQueryTextChange(String query) {
mCompetitorsList = GlobalCompetitorsList.getCompetitors();
query = query.toLowerCase();
final List<Competitor> filteredList = new ArrayList<>();
for (int i = 0; i < mCompetitorsList.size(); i++) {
final String lastName = mCompetitorsList.get(i).getLastName().toLowerCase();
final String firstName = mCompetitorsList.get(i).getFirstName().toLowerCase();
if (lastName.contains(query) || firstName.contains(query)) {
filteredList.add(mCompetitorsList.get(i));
}
}
mAdapter.setFilter(filteredList);
return true;
}
// ********* RecyclerView Adapter class *************************************************************************
public class CompetitorListAdapter extends RecyclerView.Adapter<CompetitorListAdapter.CompetitorViewHolder> {
List<Competitor> mCompetitors;
Context mContext;
public CompetitorListAdapter(Context context, List<Competitor> competitors) {
mContext = context;
mCompetitors = competitors;
}
#Override
public CompetitorListAdapter.CompetitorViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(MasterCompetitorsListActivity.this);
View itemView = inflater.inflate(R.layout.list_item_master_competitor, parent, false);
CompetitorViewHolder viewHolder = new CompetitorViewHolder(itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(CompetitorListAdapter.CompetitorViewHolder holder, final int position) {
final Competitor competitor = mCompetitorsList.get(position);
try {
holder.firstName.setText(competitor.getFirstName());
holder.lastName.setText(competitor.getLastName());
holder.memberNum.setText(competitor.getMemberNum());
holder.deleteCompetitor.setImageResource(R.drawable.ic_delete_forever_white_24dp);
holder.container.findViewById(R.id.main_container);
holder.hiddenCompetitorId.setText(competitor.getCompetitorId().toString());
} catch (Exception e) {
e.printStackTrace();
}
holder.deleteCompetitor.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager = getSupportFragmentManager();
DeleteCompetitorDialogFragment dialog = new DeleteCompetitorDialogFragment();
dialog.show(fragmentManager, DIALOG_DELETE_COMPETITOR);
// mCompetitorsList.remove(competitor); // remove from the global singleton list
// notifyItemRemoved(position);
}
});
}
#Override
public int getItemCount() {
return mCompetitorsList.size();
}
// ************* View Holder Class **************************************************************************
public class CompetitorViewHolder extends RecyclerView.ViewHolder {
public TextView firstName;
public TextView lastName;
public TextView memberNum;
public ImageButton deleteCompetitor;
public ConstraintLayout container;
public TextView hiddenCompetitorId;
boolean comptitorIsActive = false;
public CompetitorViewHolder(final View itemView) {
super(itemView);
firstName = (TextView) itemView.findViewById(R.id.first_name);
lastName = (TextView) itemView.findViewById(R.id.last_name);
deleteCompetitor = (ImageButton) itemView.findViewById(R.id.delete_competitor_button);
hiddenCompetitorId = (TextView) itemView.findViewById(R.id.competitor_id_hidden);
container = (ConstraintLayout) itemView.findViewById(R.id.main_container);
memberNum = (TextView) itemView.findViewById(R.id.member_num);
}
}
// ************ End of View Holder Class ********************************************************************
public void setFilter(List<Competitor> newList) {
mCompetitorsList = new ArrayList<>();
mCompetitorsList.addAll(newList);
notifyDataSetChanged();
}
}
// ************* End of RecyclerView Adapter class **********************************************************
}
Here is the Dialog class:
public class DeleteCompetitorDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
final GlobalCompetitorsList mCompetitorsList = GlobalCompetitorsList.get();
return new AlertDialog.Builder(getActivity())
.setTitle("Delete this Competitor?")
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// remove from the master_competitors.json file by overwriting the original file with the new
// global list
File file = new File("data/data/com.checkinsystems.ez_score/files/master_competitors.json");
if (file.exists()) {
FileOutputStream fos = null;
try {
String jsonString = new Gson().toJson(mCompetitorsList);
fos = getActivity().openFileOutput("master_competitors.json", getActivity().MODE_PRIVATE);
fos.write(jsonString.getBytes());
// somehow access the list from the calling activity to remove the item
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert fos != null;
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
})
.create();
}
}
And if it helps to understand my code, here is the Singleton class
public class GlobalCompetitorsList {
public static GlobalCompetitorsList sGlobalCompetitorsList;
public static List<Competitor> sCompetitors;
public static GlobalCompetitorsList get() {
if(sGlobalCompetitorsList == null){
return new GlobalCompetitorsList();
} else {
return sGlobalCompetitorsList;
}
}
private GlobalCompetitorsList() {
File file = new File("data/data/com.checkinsystems.ez_score/files/master_competitors.json");
String jsonString;
if(file.exists()){
BufferedReader reader = null;
List<Competitor> list;
sCompetitors = new ArrayList<>();
try {
reader = new BufferedReader(new FileReader(file));
jsonString = reader.readLine();
Type compType = new TypeToken<List<Competitor>>(){}.getType();
list = new Gson().fromJson(jsonString, compType);
addCompetitors(list);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert reader != null;
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
sCompetitors = new ArrayList<>();
}
}
public void addCompetitor(Competitor c){
sCompetitors.add(c);
}
public static void addCompetitors(List<Competitor> c){
sCompetitors.addAll(c);
}
public static List<Competitor> getCompetitors(){
return sCompetitors;
}
}
Simple just create a constructor for the Dialog that you are using
public DeleteCompetitorDialogFragment(IMyListenerCallback listener){
mListener = listener;
}
later on//
if(listener != null){
listener.doWhatYouNeed(stuffToPass);
}
Then make an interface class
public interface IMyListenerCallback{
void doWhatYouNeed(Object stuffToPass);
}
//then in your calling activity
public class MainActivity extends AppCompatActivity implements IMyListenerCallback{
private void launchDialog(){
new DeleteCompetitorDialogFragment(this).show();
}
#Override
public void doWhatYouNeed(Object stuffToPass){
}
}
Of course this is pseduo code and not tested, but hopefully you get the picture. Goodluck.

ListView is not refreshing

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)

Data on cardview are changed while scrolling RecyclerView

I am newbie to Android apps development.
I have a class, which contains RecyclerView.
public class ScreenOne extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private RecyclerView mRecyclerView;
private FilmSetAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
SwipeRefreshLayout mSwipeRefreshLayout;
RequestTask requestTask;
ArrayList<Film> listOfFilms;
ArrayList<Cinema> listOfCinemas;
ArrayList<String> cityIDs;
public ScreenOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.screen_one, container,
false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
mLayoutManager = new LinearLayoutManager(getActivity());
//mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
//mRecyclerView.setItemAnimator(new DefaultItemAnimator());
listOfFilms = new ArrayList<>();
mAdapter = new FilmSetAdapter(listOfFilms);
mRecyclerView.setAdapter(mAdapter);
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh);
mSwipeRefreshLayout.setOnRefreshListener(this);
mSwipeRefreshLayout.setColorScheme(R.color.blue, R.color.cyan, R.color.grey_blue, R.color.lightblue);
try {
updateFilms();
} catch (InterruptedException e) {
e.printStackTrace();
}
return rootView;
}
private void updateFilms() throws InterruptedException {
requestTask = new RequestTask();
try {
requestTask.execute().get();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
private boolean isNetworkConnected() {
ConnectivityManager cm =
(ConnectivityManager) getActivity().getSystemService(getActivity().CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
#Override
public void onRefresh() {
Toast.makeText(getActivity(), R.string.refresh_started, Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(true);
mAdapter.setDataset(new ArrayList<Film>());
mAdapter.notifyDataSetChanged();
try {
updateFilms();
} catch (InterruptedException e) {
e.printStackTrace();
}
DatabaseHandler database = new DatabaseHandler(getActivity());
mAdapter = new FilmSetAdapter(database.getAllFilms());
mRecyclerView.swapAdapter(mAdapter, false);
database.close();
mSwipeRefreshLayout.postDelayed(new Runnable() {
#Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), R.string.refresh_finished, Toast.LENGTH_SHORT).show();
}
}, 3000);
}
class RequestTask extends AsyncTask<Void, Void, Void> {
protected void getPreferenciesCity()
{
cityIDs = new ArrayList<>();
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
Set<String> selections = sharedPrefs.getStringSet("cities", null);
try {
Log.d("SHARED PREFERENCES CITY", selections.toString());
cityIDs.addAll(selections);
}catch (NullPointerException e){Log.d("SHARED PREFERENCES CITY", "SP are empty");}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
listOfFilms = new ArrayList<>();
getPreferenciesCity();
}
#Override
protected Void doInBackground(Void... params) {
if(isNetworkConnected()) {
DatabaseHandler database = new DatabaseHandler(getActivity());
database.clearFilms();
try {
HttpHandler httpHandler = new HttpHandler();
listOfFilms = new ArrayList<>(httpHandler.listOfFilmsRequest(cityIDs));
listOfCinemas = new ArrayList<>(httpHandler.listOfCinemasRequest());
Film film;
Cinema cinema;
for (Iterator<Film> filmiterator = listOfFilms.iterator(); filmiterator.hasNext(); ) {
film = filmiterator.next();
if (database.isInDatabase(film.getID()))
database.updateFilm(film);
else
database.addFilm(film);
}
for (Iterator<Cinema> cinemaiterator = listOfCinemas.iterator(); cinemaiterator.hasNext(); ) {
cinema = cinemaiterator.next();
if (database.CinemaIsInDatabase(cinema.getIDCinema()))
database.updateCinema(cinema);
else
database.addCinema(cinema);
}
database.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
DatabaseHandler database = new DatabaseHandler(getActivity());
mAdapter.setDataset(database.getAllFilms());
mAdapter.notifyDataSetChanged();
}
}
}
It executes a method, which is placed in the AsyncTask class. This method downloads data from server, puts it to database first and after that sets the recycler view adapter. The problem is that sometimes text data are changed while scrolling it. See attached video.
Code of adapter is:
public class FilmSetAdapter extends RecyclerView.Adapter<FilmSetAdapter.ViewHolder>{
private ArrayList<Film> mDataset;
final static String LOG_TAG = "FilmSetAdapter";
public void setDataset(ArrayList<Film> allFilms) {
mDataset = new ArrayList<>(allFilms);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public static TextView filmTitle;
public TextView country;
public TextView ticketsFrom;
public TextView rating;
public TextView format;
public ImageView poster;
public int id;
public ViewHolder(final View itemView) {
super(itemView);
filmTitle = (TextView) itemView.findViewById(R.id.filmtitle);
country = (TextView)itemView.findViewById(R.id.country);
ticketsFrom = (TextView) itemView.findViewById(R.id.ticketsfrom);
rating = (TextView)itemView.findViewById(R.id.rating);
poster = (ImageView) itemView.findViewById(R.id.poster);
format = (TextView) itemView.findViewById(R.id.format);
format.setTypeface(null, Typeface.BOLD_ITALIC);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cardview, parent, false);
final ViewHolder vh = new ViewHolder(v);
v.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
Log.d(LOG_TAG, "Нажата карточка. Вызов из activity "+v.toString());
Intent intent = new Intent(v.getContext(),FilmInfoActivity.class);
intent.putExtra("EXTRA_FILM_ID", vh.id);
v.getContext().startActivity(intent);
}
});
return vh;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.filmTitle.setText(mDataset.get(position).getTitle().toString()+" ID="+mDataset.get(position).getID()+" POS="+position);
holder.country.setText(mDataset.get(position).getCountry());
holder.ticketsFrom.setText(holder.ticketsFrom.getContext().getString(R.string.tickets_from) +
mDataset.get(position).getRating().toString());
holder.rating.setText(holder.rating.getContext().getString(R.string.rating_kinopoisk) +
mDataset.get(position).getRating());
holder.id = mDataset.get(position).getID();
holder.format.setText(mDataset.get(position).getFormat());
Picasso.with(holder.poster.getContext()).
load(mDataset.get(position).getPoster()).
skipMemoryCache().
into(holder.poster);
}
#Override
public int getItemCount() {
if(mDataset != null)
return mDataset.size();
return 0;
}
public FilmSetAdapter(ArrayList<Film> myDataset) {
mDataset = new ArrayList<>(myDataset);
}
}
I have no clue on how to sort it out.
it seem to that there is a typo mistake in your code, look at that, you have in your ViewHolder:
public static TextView filmTitle;
But then you work with it like with your other fields:
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.filmTitle.setText(mDataset.get(position).getTitle() + ...);
...
}
A little advice for you as a newbie: just.. pay more attention to your code, and you'll be fine in programming :)

Categories

Resources