I'm developing a simple To do App. The recyclerview gets items from Sqlite datebase.
By clicking the specific item, i want to assign date from Calendar to that item. Now i want to schedule each item in recyclerview with date. I'm facing problem to assign date/time to specific item because when i add date, it shows as next item in recyclerview
#Override
public void onBindViewHolder(#NonNull final MyHolder holder, final int position) {
final InboxViewModel inboxViewModel = (InboxViewModel) arrayList.get(position);
holder.textView.setText(inboxViewModel.getText());
holder.date.setText(inboxViewModel.getDate());
setAnimation(holder.itemView, position);
MainClass is:
public class InboxFragment extends Fragment{
RecyclerView inbox_recyclerview;Inbox_Adapter adapter;
ArrayList arrayList;
String myId,myTask,myDate; int pos;String dt;
MyDatabase db;
private InboxViewModel inboxViewModel;
FragmentHelper fragmentHelper; BottomSheetListener bottomSheetListener;
RelativeLayout relativeLayout; DataController dataController;
ActivityMain activityMain;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
fragmentHelper = (FragmentHelper) context;
bottomSheetListener=(BottomSheetListener)context;
dataController=(DataController)context;
activityMain=(ActivityMain)context;
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_inbox, container, false);
relativeLayout=root.findViewById(R.id.relative1);
arrayList=new ArrayList<>();
inbox_recyclerview=root.findViewById(R.id.inbox_recycler);
inbox_recyclerview.setLayoutManager(new LinearLayoutManager(getContext()));
inbox_recyclerview.setHasFixedSize(true);
// dataController.onGetData();
MyDatabase myDatabase = new MyDatabase(getContext());
Cursor c = myDatabase.getData();
if (c.getCount() == 0) {
Toast.makeText(getContext(), "no data available", Toast.LENGTH_SHORT).show();
} else {
if (c.moveToFirst()) {
do {
myId = c.getString(c.getColumnIndex(myDatabase.id));
myTask = c.getString(c.getColumnIndex(myDatabase.task_col));
myDate = c.getString(c.getColumnIndex(myDatabase.date_col));
inboxViewModel =new InboxViewModel(myTask,myId,myDate);
arrayList.add(inboxViewModel);
} while (c.moveToNext());
{
adapter=new Inbox_Adapter(getActivity(),arrayList,fragmentHelper,bottomSheetListener);
inbox_recyclerview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
inbox_recyclerview.setItemAnimator(new DefaultItemAnimator());
inbox_recyclerview.addItemDecoration(new DividerItemDecoration(getActivity(),DividerItemDecoration.VERTICAL));
return root;
}
}
MainFragmentClass is:
public class InboxFragment extends Fragment{
RecyclerView inbox_recyclerview;Inbox_Adapter adapter;
ArrayList arrayList;
String myId,myTask,myDate; int pos;String dt;
MyDatabase db;
private InboxViewModel inboxViewModel;
FragmentHelper fragmentHelper; BottomSheetListener bottomSheetListener;
RelativeLayout relativeLayout; DataController dataController;
ActivityMain activityMain;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
fragmentHelper = (FragmentHelper) context;
bottomSheetListener=(BottomSheetListener)context;
dataController=(DataController)context;
activityMain=(ActivityMain)context;
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_inbox, container, false);
relativeLayout=root.findViewById(R.id.relative1);
arrayList=new ArrayList<>();
inbox_recyclerview=root.findViewById(R.id.inbox_recycler);
inbox_recyclerview.setLayoutManager(new LinearLayoutManager(getContext()));
inbox_recyclerview.setHasFixedSize(true);
// dataController.onGetData();
MyDatabase myDatabase = new MyDatabase(getContext());
Cursor c = myDatabase.getData();
if (c.getCount() == 0) {
Toast.makeText(getContext(), "no data available", Toast.LENGTH_SHORT).show();
} else {
if (c.moveToFirst()) {
do {
myId = c.getString(c.getColumnIndex(myDatabase.id));
myTask = c.getString(c.getColumnIndex(myDatabase.task_col));
myDate = c.getString(c.getColumnIndex(myDatabase.date_col));
inboxViewModel =new InboxViewModel(myTask,myId,myDate);
arrayList.add(inboxViewModel);
} while (c.moveToNext());
{
adapter=new Inbox_Adapter(getActivity(),arrayList,fragmentHelper,bottomSheetListener);
inbox_recyclerview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
Related
I have a Navigation menu with nav menu on it. When clicked on each nav menu, the specific fragment is opened.For example, when I click on Words nav menu, words item display with recyclerView items on it. I'm fetching data from offline and external SQLite database and display on recyclerView items. Now I want to fetch data in another thread, NOT in the main thread, because I want increase loading speed data and app performance. But I don't know how to do this. please help me with a code. I read the same subject on the internet, but I still now have my issue.
this is my AllWordsFragment
public class AllWordsFragment extends Fragment {
private List<WordsList> wordsLists = new ArrayList<>();
private Cursor cursor;
ProgressBar progressBar;
RecyclerView recyclerView;
AllWordsAdapter allWordsAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.all_words_fragment, container, false);
progressBar = view.findViewById(R.id.progressBar);
progressBar.setMax(600);
allWordsAdapter = new AllWordsAdapter(getActivity(), wordsLists);
allWordsAdapter.notifyDataSetChanged();
recyclerView = view.findViewById(R.id.recyclerViewAllWords);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(allWordsAdapter);
loadingWords();
return view;
}
private void loadingWords() {
WordDatabase wordDatabase = new WordDatabase(getActivity());
try {
wordDatabase.createDatabase();
wordDatabase.openDatabase();
} catch (SQLiteException e) {
e.printStackTrace();
}
try {
cursor = wordDatabase.QueryData("SELECT Word, Definition, Example, WordList, ImageWord FROM Words");
if (cursor != null && cursor.moveToFirst()) {
do {
WordsList wordList = new WordsList();
wordList.setWordTitle(cursor.getString(0));
wordList.setDefinition(cursor.getString(1));
wordList.setExample(cursor.getString(2));
wordList.setVocubList(cursor.getString(3));
wordList.setImageWord(cursor.getString(4));
wordsLists.add(wordList);
} while (cursor.moveToNext());
wordDatabase.close();
}
} catch (SQLiteException w) {
w.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
and this is my AllWordsAdapter
public class AllWordsAdapter extends RecyclerView.Adapter {
private int lastPosition = -1;
protected Context context;
private List<WordsList> wordsListList = new ArrayList<>();
public AllWordsAdapter(Context context, List<WordsList> wordsListList) {
this.context = context;
this.wordsListList = wordsListList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.all_words_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
WordsList wordsList = wordsListList.get(position);
holder.wordTitle.setText(wordsList.getWordTitle());
holder.definitionWord.setText(Html.fromHtml(wordsList.getDefinition()));
holder.exampleWord.setText(Html.fromHtml(wordsList.getExample()));
holder.labelWordList.setLabelText(wordsList.getVocubList());
//get image from assets with Glide.
String pathImage = wordsList.getImageWord();
String assetsPath = "file:///android_asset/";
Glide.with(context)
.asBitmap()
.load(Uri.parse(assetsPath + "" + pathImage))
.into(holder.wordImage);
Log.d("path", assetsPath + "" + pathImage);
Typeface headerFont = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Bold.ttf");
holder.wordTitle.setTypeface(headerFont);
Typeface customFont = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Italic.ttf");
holder.exampleWord.setTypeface(customFont);
holder.definitionWord.setTypeface(customFont);
//cal animation function
setAnimation(holder.itemView, position);
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, AllWordsDetails.class);
intent.putExtra("word", holder.wordTitle.getText().toString());
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return wordsListList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CircleImageView wordImage;
private LabelTextView labelWordList;
private TextView wordTitle, definitionWord, exampleWord;
private RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
wordTitle = itemView.findViewById(R.id.allWordTitle);
wordImage = itemView.findViewById(R.id.circleHeaderImage);
exampleWord = itemView.findViewById(R.id.exampleAllWord);
definitionWord = itemView.findViewById(R.id.definitionAllWord);
labelWordList = itemView.findViewById(R.id.labelWordList);
relativeLayout = itemView.findViewById(R.id.relativeAllWords);
}
}
private void setAnimation(View viewToAnimation, int position) {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition) {
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(new Random().nextInt(501));//to make duration random number between [0,501)
viewToAnimation.startAnimation(scaleAnimation);
lastPosition = position;
}
}
}
I know must be use AsyncTask and do this in background, but I don't know how do this ? Please help me with a code. Thanks .
create an AsyncTask class inside your class:
class WordLoaderTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
loadingWords();
}
protected void onPostExecute(Void param) {
allWordsAdapter.notifyDataSetChanged();
}
}//asyncClass
replace calling loadingWords() in onCreate() with this line:
new WordLoaderTask().execute();
if you (for some reason or a way of using app) start getting duplicates in your ListView, then add wordsLists.clear(); as first line inside the do{} in loadingWords() method
Try like this
public class AllWordsFragment extends Fragment {
private List<WordsList> wordsLists = new ArrayList<>();
private Cursor cursor;
ProgressBar progressBar;
RecyclerView recyclerView;
AllWordsAdapter allWordsAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.all_words_fragment, container, false);
progressBar = view.findViewById(R.id.progressBar);
progressBar.setMax(600);
allWordsAdapter = new AllWordsAdapter(getActivity(), wordsLists);
allWordsAdapter.notifyDataSetChanged();
recyclerView = view.findViewById(R.id.recyclerViewAllWords);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(allWordsAdapter);
loadingWords();
return view;
}
private static LoadWordsTask extends AsyncTask<Void, Void, List<WordsList>> {
private Context context;
private AllWordsAdapter adapter;
private List<WordsList> wordsLists;
public LoadWordsTask(Context context, AllWordsAdapter adapter, List<WordsList> wordsLists) {
this.context = context;
this.adapter = adapter;
this.wordsLists = wordsLists;
}
#Override
public List<WordsList> doInBackground() {
List<WordsList> data = new ArrayList<>();
WordDatabase wordDatabase = new WordDatabase(getActivity());
try {
wordDatabase.createDatabase();
wordDatabase.openDatabase();
} catch (SQLiteException e) {
e.printStackTrace();
}
try {
cursor = wordDatabase.QueryData("SELECT Word, Definition, Example, WordList, ImageWord FROM Words");
if (cursor != null && cursor.moveToFirst()) {
do {
WordsList wordList = new WordsList();
wordList.setWordTitle(cursor.getString(0));
wordList.setDefinition(cursor.getString(1));
wordList.setExample(cursor.getString(2));
wordList.setVocubList(cursor.getString(3));
wordList.setImageWord(cursor.getString(4));
data.add(wordList);
} while (cursor.moveToNext());
wordDatabase.close();
}
} catch (SQLiteException w) {
w.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
return data;
}
#Override
public void onPostExecute(List<WordsList> data) {
this.wordsLists.addAll(data);
this.adapter.notifyDataSetChanged();
}
}
}
public class MistakeGridFragment extends Fragment {
private Set<String> mistakeSelected = new HashSet<>();
private ListView listView;
private ITransfer iTransfer;
public MistakeGridFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mistake_dialog, container, false);
MistakeListHelper mistakeListHelper = new MistakeListHelper(getActivity());
mistakeLists.addAll(mistakeListHelper.getAllMistakegrid());
init(view);
return view;
}
#TargetApi(23)
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
iTransfer = (ITransfer) context;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
#Override
public void onAttach(Activity context) {
super.onAttach(context);
try {
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
iTransfer = (ITransfer) context;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
private void init(View view) {
relativeLayout = (LinearLayout) view.findViewById(R.id.mistakegrid_mainly);
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
// adding number of column
for (int i = 0; i < mistakeLists.size(); i++) {
String listvalue = mistakeLists.get(i).getListTypeValue();
String name = mistakeLists.get(i).getListTypeName();
Type type = new TypeToken<ArrayList<HashMap<Double, String>>>() {
}.getType();
ArrayList<HashMap<Double, String>> myMap = gson.fromJson(listvalue, type);
for (int j = 0; j < myMap.size(); j++) {
HashMap<Double, String> hash = myMap.get(j);
view = setTypeOfMistake(name, hash, j);
}
relativeLayout.addView(view);
}
}
private View setTypeOfMistake(final String mistakeName, HashMap<Double, String> hashValue, int i) {
optionsArraylist = new ArrayList<>();
//main mistake grid layout here added column
LayoutInflater layoutInflatermain = LayoutInflater.from(getActivity());
View main = layoutInflatermain.inflate(R.layout.mistake_column_layout, null);
LinearLayout linearLayout = (LinearLayout) main.findViewById(R.id.linaerlayout);
//here added row layout for each column
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater.inflate(R.layout.mistake_row_layout, null);
TextView mistakeType = (TextView) view.findViewById(R.id.header_tv);
listView = (ListView) view.findViewById(R.id.listview);
Set set = (Set) hashValue.entrySet();
Iterator it = set.iterator();
optionsArraylist.clear();
while (it.hasNext()) {
HashMap<Double, String> hashMap = new HashMap<>();
Map.Entry entry = (Map.Entry) it.next();
optionsArraylist.add((String) entry.getValue());
hashMap.put((Double) entry.getKey(), (String) entry.getValue());
mistakeHashArryList.add(hashMap);
}
mistakeType.setText(mistakeName + "");
ArrayAdapter<String> adaptor = new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, optionsArraylist);
listView.setAdapter(adaptor);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
toggleSelection(optionsArraylist.get(position).toString(), view);
//Toast.makeText(QuestionActivity.this,parent.getItemAtPosition(position).toString(),Toast.LENGTH_SHORT).show();
if (mistakeSelected.contains(parent.getItemAtPosition(position).toString())) {
mistakeSelected.remove(parent.getItemAtPosition(position).toString());
view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.md_blue_grey_400));
} else {
mistakeSelected.add(parent.getItemAtPosition(position).toString());
view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.md_blue_grey_500));
}
}
});
linearLayout.addView(view);
return linearLayout;
}
public boolean getMistake() {
if (mistakeSelected.size() > 0) {
iTransfer.getData(mistakeSelected);
return true;
} else {
new MyUtils(getActivity()).setMessageShort("Please selected any one mistake");
}
return false;
}
public interface ITransfer {
public void getData(Set<String> strings);
}
public class MistakeReasonFragment extends Fragment implements MistakeGridFragment.ITransfer {
private ArrayList<String> arrayList = new ArrayList<>();
private TableLayout tableLayout;
private LayoutInflater layoutInflater;
private LinearLayout addMistake_row;
public MistakeReasonFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mistake_reason_layout, container, false);
init(view);
return view;
}
private void init(View view) {
tableLayout = (TableLayout) view.findViewById(R.id.tablelayout);
addMistake_row = (LinearLayout) view.findViewById(R.id.linaerl_row);
}
#Override
public void onPause() {
EventBus.getDefault().unregister(this);
super.onPause();
}
#Override
public void getData(Set<String> strings) {
Log.v("value size ", strings.size() + " ");
}
}
LogCat:
java.lang.ClassCastException: com.android.root.ui.activity.QueActivity cannot be cast to com.tapasya.root.tapasya.ui.fragment.MistakeGridFragment$ITransfer
10-27 11:44:54.811 30409-30409/com.tapasya.root.tapasya W/System.err:
at com.android.root.ui.fragment.MistakeGridFragment.onAttach(MistakeGridFragment.java:70)
10-27 11:44:54.811 30409-30409/com.android.root W/System.err:
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1043)
10-27 11:44:54.811 30409-30409/com.android.root W/System.err:
at android.support.v4.app.BackStackRecord.setLastIn(BackStackRecord.java:838)
10-27 11:44:54.811 30409-30409/com.android.root W/System.err:
at android.support.v4.app.BackStackRecord.calculateFragments(BackStackRecord.java:861)
Since, the context instance in onAttach() is the instance of the container activity for the fragment, make sure that the container activity has implemented the ITransfer callback, otherwise you cannot cast the instance of the context object in onAttach() to the ITransfer reference variable.
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)
I'm trying to get all the contacts from my SQLite database.
Everything is working fine, I just want to make it asynchronous and not run in the main thread, to not influence the UI.
public List<contacts> getAllcontacts() {
List<contacts> contactsl = new LinkedList<contacts>();
String query = "SELECT * FROM contacts WHERE show is not 'NOTSIGNEDUP'"
+" ORDER BY name COLLATE NOCASE;";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
contacts contact = null;
if (cursor.moveToFirst()) {
do {
contact = new contacts();
contact.setName(cursor.getString(1));
contact.setNumero(cursor.getString(3));
contact.setProfil(cursor.getString(2));
contact.setShow(cursor.getString(5));
contact.setBlocked(cursor.getString(4));
contact.setObjectid(cursor.getString(6));
contactsl.add(contact);
} while (cursor.moveToNext());
}
return contactsl;
}
I'm calling this function from my activity :
final sql s = sql.getInstance(getContext());
if (ContactsList != null) {
ContactsList.clear();
ContactsList.addAll(list);
ContactsList.addAll(s.getAllcontacts_());
cAdapter.notifyDataSetChanged();
}
Is there any way to make s.getAllcontacts() runs asyn
I made my Fragment like this :
public class ContactsFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<contacts>> {
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private ContactsAdapter cAdapter;
private List<contacts> ContactsList;
public ContactsFragment() {
// Required empty public constructor
}
public void set(List<contacts> list) {
final sql s = sql.getInstance(getContext());
if (ContactsList != null) {
ContactsList.clear();
ContactsList.addAll(list);
ContactsList.addAll(s.getAllcontacts_());
cAdapter.notifyDataSetChanged();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_blank, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View view = getView();
if(view != null) {
mRecyclerView = (RecyclerView) view.findViewById(R.id.contacts_recycler);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(view.getContext());
mRecyclerView.setLayoutManager(mLayoutManager);
final sql s = sql.getInstance(view.getContext());
ContactsList = new ArrayList<contacts>();
cAdapter = new ContactsAdapter(ContactsList, mRecyclerView);
mRecyclerView.setAdapter(cAdapter);
getLoaderManager().initLoader(0, null, this);
}
}
#Override
public android.support.v4.content.Loader<List<contacts>> onCreateLoader(int id, Bundle args) {
return new AppListLoader(this.getContext());
}
#Override
public void onLoadFinished(android.support.v4.content.Loader<List<contacts>> loader, List<contacts> data) {
ContactsList.addAll(data);
cAdapter.notifyDataSetChanged();
}
#Override
public void onLoaderReset(android.support.v4.content.Loader<List<contacts>> loader) {
}
public static class AppListLoader extends AsyncTaskLoader<List<contacts>> {
final sql s = sql.getInstance(getContext());
public AppListLoader(Context context) {
super(context);
}
#Override
public List<contacts> loadInBackground() {
return s.getAllcontacts();
}
}
}
in addition to what #CommonsWare suggests, you could also use give to the AsyncTaskLoader a try. You could define
public static class AppListLoader extends AsyncTaskLoader<List<Contact>> {
and move your querying logic in loadInBackground().
Your Activity/Fragment will make then use of the LoaderManager. It will implement LoaderManager.LoaderCallbacks<List<Contact>> and onCreateLoader will return a new instance of your AsyncTaskLoader. The List<Contact> will be delivered as part of onLoadFinished
I am unable to refresh my ListView in ListFragment with new data. Instead the new data is added to the previous.
The time period is from 6AM to 5PM for each entity. Then new data is appended to the list restarting at 6AM for another entity. The data for the first entity should be cleaned before the second is added to the ListView.
Here is the code:
public class FragmentStatePagerSupport extends FragmentActivity {
static final int NUM_ITEMS = 4; //control number of fragments
MyAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(null);
mPager.setAdapter(mAdapter);
}
//===============================================================================================
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
fragNumber = position;
return ArrayListFragment.newInstance(position);
}
}
//===============================================================================================
public static class ArrayListFragment extends ListFragment {
Integer mNum;
String FORMAT_LINE = "%s%7s%7s%10s%16s";
static ArrayListFragment newInstance(int num) {
ArrayListFragment f = new ArrayListFragment();
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNum = getArguments() != null ? getArguments().getInt("num") : 1;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_pager_list, container, false);
View tv = v.findViewById(R.id.text);
View tvd = v.findViewById(R.id.tv_description);
String title = "";
switch (mNum){
case 0:title = MyGlobals.getInstance().getToday();break;
case 1:title = MyGlobals.getInstance().getTomorrow();break;
case 2:title = MyGlobals.getInstance().getDayAfter();break;
case 3:title = MyGlobals.getInstance().getDayDayAfter();break;
}
((TextView) tv).setText(MyGlobals.getInstance().getName() + " on " + title);
((TextView) tvd).setText(String.format(FORMAT_LINE, "time", "temp", "rain", "wind", "weather"));
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<Data> row = Data.getRows(mNum);
ListViewAdapter adapter = new ListViewAdapter(getActivity(), row);
getListView().setAdapter(null);
getListView().setAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
v.setBackgroundColor(getResources().getColor(R.color.blue));
}
}
//==============================================================================================
public static class ListViewAdapter extends ArrayAdapter<Data> {
public static class ViewHolder{
TextView time;
TextView temp;
TextView rain;
TextView wind_speed;
TextView weather;
}
public ListViewAdapter(Context context, ArrayList<Data> list) {super(context, R.layout.text_listview, list); }
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Data data = getItem(position);
ViewHolder holder;
if(convertView == null){
holder=new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView=inflater.inflate(R.layout.text_listview,parent,false);
holder.time=(TextView) convertView.findViewById(R.id.time);
holder.temp=(TextView) convertView.findViewById(R.id.temp);
holder.rain=(TextView) convertView.findViewById(R.id.rain);
holder.wind_speed=(TextView) convertView.findViewById(R.id.wind);
holder.weather=(TextView) convertView.findViewById(R.id.weather);
convertView.setTag(holder);
}else{
holder=(ViewHolder) convertView.getTag();
}
holder.time.setText(data.time);
holder.temp.setText(data.temp);
holder.rain.setText(data.rain);
holder.wind_speed.setText(data.wind_speed);
holder.weather.setText(data.weather);
return convertView;
}
}
}
This last piece populates the ListView. The calls adapter.clear() and adapter.notifyDataSetChanged() does not resolve the problem.
There is a similar question from 3 years ago How update ListView in ListFragment from FragmentActivity? still without accepted response despite the 6836 views.
Thanks a Lot.
The GetRows(mNum) piece as requested:
public class Data {
public String time;
public String temp;
public String rain;
public String wind_speed;
public String weather;
public Data(String time, String temp, String rain, String wind_speed, String weather) {
this.time = time;
this.temp = temp;
this.rain = rain;
this.wind_speed = wind_speed;
this.weather = weather;
}
public static ArrayList<Data> getRows(int fragNumber) {
int mNum = fragNumber;
int size;
String myList[] = null;
ArrayList<Data> list = new ArrayList<Data>();
switch (mNum) {
case 0://Today
size = MyGlobals.getInstance().getToday("time").size();
myList = new String[size];
for (int i = 0; i < size; i++) {
String time = (String) MyGlobals.getInstance().getToday("time").get(i);
String temp = (String) MyGlobals.getInstance().getToday("temperature").get(i);
String wind_speed = (String) MyGlobals.getInstance().getToday("wind_speed").get(i);
String pop = (String) MyGlobals.getInstance().getToday("pop").get(i);
//String wind_gust = (String) MyGlobals.getInstance().getToday("wind_gust").get(i); //when null breaks code
String weather = (String) MyGlobals.getInstance().getToday("weather").get(i);
if (time.length() == 4) time = "0" + time;
if (wind_speed.length() == 1) wind_speed = "0" + wind_speed;
if (pop.length() == 1) pop = "0" + pop;
list.add(new Data(time,temp,pop,wind_speed,weather));
}
return list;
case 1://Tomorrow
...snip... same as above with pertinent variables,...
case 2://DayAfter
...snip...
case 3://DayDayAfter
...snip....
case 4:// is an error
Log.d("***error***", "list got to case 5");
}
return list;
}
}
Try this;
Before adding new list of Data to the existing list, use list.clear();
Add new Data to the list and you should have only newly added data in the list..
pass the list to your adapter class.
Notify adapter of the new data i.e. adapter.notifyDataSetChanged()
You are returning list twice in your getRows()
remove the "return list" before the case structure
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
// Clear old list here before adding new one.
if (list! = null)
{
list.clear();
}
// Add New list
list = Data.getRows(mNum);
ListViewAdapter adapter = new
ListViewAdapter(getActivity(), list);
getListView().setAdapter(adapter);
adapter.notifyDataSetChange();
}
It's because everytime you set an Adapter, it will really be added., remove all its data first before setting again so it will be like
mPager.setAdapter(null);
before doing
mPager.setAdapter(mAdapter);