What triggers and what happens on onPageDataChanged? - android

In a project I am working on, there is a class that uses Modelcallbacks. One of its callbacks is onPageDataChanged.
I have searched on the net but cannot find what triggers and what happens on the callback function.
Can someone please explain it to me? Thanks in advance!
#Override
public void onPageDataChanged(Page changedPage) {
ArrayList<ReviewItem> reviewItems = new ArrayList<ReviewItem>();
for (Page page : mWizardModel.getCurrentPageSequence()) {
page.getReviewItems(reviewItems);
}
Collections.sort(reviewItems, new Comparator<ReviewItem>() {
#Override
public int compare(ReviewItem a, ReviewItem b) {
return a.getWeight() > b.getWeight() ? +1 : a.getWeight() < b.getWeight() ? -1 : 0;
}
});
mCurrentReviewItems = reviewItems;
if (mReviewAdapter != null) {
mReviewAdapter.notifyDataSetInvalidated();
}
}

Related

Strange behavior - App suddenly producing ANR

I know it sounds strange/ridiculous, but I am having this issue
Update#2
I am sharing the code that is indicated by #EpicPandaForce.
SyncService.onNetworkSuccess
public void onNetworkCallSuccess(Response response) {
List<TransactionHistory> historyList = (List<TransactionHistory>) response.body();
if(historyList != null && historyList.size() > 0) {
TransactionHistory max = Collections.max(historyList, new Comparator<TransactionHistory>() {
#Override
public int compare(TransactionHistory o1, TransactionHistory o2) {
return o1.getUpdatedAt().compareTo(o2.getUpdatedAt());
}
});
if(max != null) {
session.putStringForKey(Session.timeStamp, String.valueOf(max.getUpdatedAt()));
}
for(TransactionHistory history : historyList) {
String id;
if(history.getTo().equals(history.getFrom()) ||
history.getFrom().equals(session.getStringForKey(Session.fpIdKey)))
id = history.getTo();
else id = history.getFrom();
LatestTransactionResponse latestTransactionResponse = new LatestTransactionResponse();
DateTransactionResponse dateTransactionResponse = new DateTransactionResponse(DateUtility.getDateFromEpoch(history.getEpoch()));
dateTransactionResponse.addTransaction(history);
latestTransactionResponse.setArchived(history.isArchived());
latestTransactionResponse.addTransaction(history);
latestTransactionResponse.setId(id);
dateTransactionResponse.setId(id);
LatestTransactionRepository.getInstance().addLatestTransaction(realm,
latestTransactionResponse);
ContactTransactionRepository.getInstance().addNewTransaction(realm, dateTransactionResponse, id);
}
try {
Activity temp = MyFirebaseMessagingService.getRunningActivity();
if(temp != null) {
if(temp instanceof MainActivity) {
((MainActivity) temp).refreshLatestTransactions();
} else if(temp instanceof TransactionDetailActivity) {
((TransactionDetailActivity) temp).refreshOnMainThread();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
addNewTransaction
public void addNewTransaction(Realm realm, final DateTransactionResponse response, final String id) {
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
List<TransactionHistory> tempHistoryList;
DateTransactionResponse temp = realm
.where(DateTransactionResponse.class)
.equalTo("id", id)
.equalTo("date", response.getDate())
.findFirst();
if(temp == null)
realm.insertOrUpdate(response);
else {
tempHistoryList = temp.getTransactions();
for(TransactionHistory history : response.getTransactions()) {
boolean found = false;
for(int i=0; i < tempHistoryList.size(); i++) {
if (history.getId().equals(tempHistoryList.get(i).getId())) {
if(history.getStatus().equals(tempHistoryList.get(i).getStatus())) {
found = true;
break;
} else {
tempHistoryList.get(i).setStatus(history.getStatus());
}
}
}
if(!found)
tempHistoryList.add(history);
}
//realm.insertOrUpdate(temp);
realm.copyToRealm(temp);
//DateTransactionResponse transactionResponse = temp;
//temp.deleteFromRealm();
//realm.insertOrUpdate(temp);
}
}
});
//removeDuplicateTransactions(realm);
}
removeDuplicateTransaction
private void removeDuplicateTransactions(Realm realm) {
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
RealmQuery<DateTransactionResponse> query = realm.where(DateTransactionResponse.class);
RealmResults<DateTransactionResponse> results = query.findAll();
List<DateTransactionResponse> transactions = new ArrayList<>(results);
for(DateTransactionResponse response : transactions) {
List<TransactionHistory> historyList = response.getTransactions();
Set<TransactionHistory> historySet = new LinkedHashSet<>(historyList);
RealmList<TransactionHistory> histories = new RealmList<>();
histories.addAll(new ArrayList<>(historySet));
response.setTransactions(histories);
realm.copyToRealm(response);
}
}
});
}
Update#1
There are 3 tabs with RecyclerViews on my main screen. Below are the implementation of Adapter for all three.
I have been developing an App for quite a time. It has been working just fine and I occasionally work to improve its performance. It is still under development. Some days ago, I cut-out the branch and done nothing notable (just one or two bug fixes) and started testing it and OOPS it started giving ANR's. I revert back to previous branch and very strangely it started giving me the same result. I have removed all changes and tried, still the same result. I am not sure what's happening. I tried to study traces.txt, but couldn't find waiting to lock as suggested in this SO answer.
I have also difficulty reading traces, couldn't find the culprit. Here is the traces.txt file.
I am using Realm as Database in my application and couldn't find a way to perform operations on Realm on other thread. I tried to find any other culprit in code, but all is till the same as before which was working perfectly fine.
Hierarchy
Here is the App Hierarchy.
Login screen is shown and user enters PIN. Then comes the main screen. Main screen contains 4 tabs, just like WhatsApp i.e first tab is camera and rest contains RecyclerViews in which data is being populated from Realm. ANR is only happening here. Keeping in mind that it was literally perfect some days ago until I took branch out and fixed some bugs, which were not even related to the main screen.
Any help or direction is highly appreciated.

RecyclerView not clearing (notifyDataSetChanged not working)

I've had a look everywhere on here and nothing is related to my problem. Basically I've implemented a feature which changes the reading direction of my app (1 or -1) now I can get it to initially change direction and it works really well but when I get it to change back (using the same code but changing the direction) it just doesn't update. Just seems like notifyDataSetChanged(); doesn't want to work the second time...?
My code is as as follows:
private void flip() {
if (!isFlipped) {
mData.getItems().removeAll(mData.getItems());
mAdapter.notifyDataSetChanged();
isFlipped = true;
loadData(false, -1);
closeMenu();
} else {
mData.getItems().removeAll(mData.getItems());
mAdapter.notifyDataSetChanged();
isFlipped = false;
loadData(false, 1);
closeMenu();
}
}
What am I doing wrong?
Again, thanks in advance :)
Implement a public method in your RecyclerView code, e.g:
public void clearAll(){
mData.clear();
this.notifyDataSetChanged();
}
And then call that function from your activity (or Fragment):
private void flip() {
if (!isFlipped) {
mAdapter.clearAll();
isFlipped = true;
loadData(false, -1);
closeMenu();
} else {
mAdapter.clearAll();
isFlipped = false;
loadData(false, 1);
closeMenu();
}
}

Android - Circular array

I have a array of jokes
String jokes[]={"x","y","z","j"};
i am using two methods next and previous to go front and back.
public void nextJoke(View view) {
if (jokeNumber < jokes.length - 1) {
jokeNumber++;
tv1.setText(jokes[jokeNumber]);
}
}
public void prevJoke(View view) {
if (jokeNumber > 0) {
jokeNumber--;
tv1.setText(jokes[jokeNumber]);
}
I want to give this list a endless scroll functionality .
That means if the user next or previous - and list reaches the last three elements , it should again start from first element.
How can i achieve this functionality .
This is more of a programming question .
Any Help will be highly appreciated.
Using the remainder operator, you'll get the required behavior.
Replace:
jokeNumber++;
with:
jokeNumber = ++jokeNumber % jokes.length;
and do the same for jokeNumber--;
On next:
next(){
jokeNumber++;
if(jokeNumber>=jokes.length) { jokeNumber =0;}
}
on previous:
previous(){
jokeNumber--;
if(jokeNumber<=0) { jokeNumber =jokes.length;}
}
public void nextJoke(View view) {
if (jokeNumber < jokes.length ) {
jokeNumber = ++jokeNumber % jokes.length;
tv1.setText(jokes[jokeNumber]); } }
public void prevJoke(View view) {
if (jokeNumber > 0) {
jokeNumber = --jokeNumber % jokes.length;
tv1.setText(jokes[jokeNumber]);
}

Using popBackStack() in Android does not update android-listview with Firebase data

At the beginning of the chat app user see a list off groups (listview group) available and the user have the possibility to create a new group or click on some off the available groups and then start to write messages (listview messages). The functions CreateNewMessage and CreateNewGroup pushes information to firebase correctly
Above scenarios works finne problems arise when user navigates backwards (popBackStack()) from listview with messages to GroupFragment, here should user be presented a list off available groups but the listview is empty. The ReadGroupData() function is not reading the already created groups from firebase and inserts them in the group listview. How to make this happen?
GroupFragment:
public void ReadGroupData() {
Firebase firebaserootRef = new Firebase("https://000.firebaseio.com");
firebaserootRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String s) {
if (snapshot.getValue() != null) {
Group newGroup = new Group((String)snapshot.child("name").getValue(),
(String) snapshot.child("id").getValue());
if(!groupKeyValues.contains(newGroup.GetId())) {
groupKeyValues.add(newGroup.GetId());
AddToLstViewGroup(newGroup);
System.out.println("Read group data from firebase and
inserted in listView");
}
}
}
});
}
public void AddToLstViewGroup(Group newGroup) {
groupNameList.add(newGroup);
if(groupAdapter == null) {
groupAdapter = new GroupAdapter(getActivity(), groupNameList);
}
if (lstViewGroup == null) {
lstViewGroup = (ListView) getView().
findViewById(R.id.listView_group);
}
lstViewGroup.setOnItemClickListener(onItemClickListener);
lstViewGroup.setOnItemLongClickListener(onItemLongClickListener);
groupAdapter.notifyDataSetChanged();
lstViewGroup.setAdapter(groupAdapter);
}
ChatFragment:
public void ReadChatMessages(Firebase firebaseRootRef) {
firebaseRootRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot snapshot, String s) {
if (snapshot.child(GetGroupId()).child("messages").
getChildren() != null) {
for (DataSnapshot c :
snapshot.child(GetGroupId()).child("messages").getChildren()) {
String key = c.getKey();
Message newMessage = new Message();
newMessage.SetFrom((String) c.child("from").getValue());
newMessage.SetMsg((String)
c.child("message").getValue());
newMessage.SetTime((String) c.child("time").getValue());
newMessage.SetId((String) c.child("id").getValue());
if ((!msgKeyValues.contains(key)) ||
newMessage.GetFrom() != "") {
msgKeyValues.add(key);
AddToLstViewChat(newMessage);
//Automatic scrolls to last line in listView.
lstViewChat.setSelection(chatAdapter.getCount() -1);
}
}
}
}
public void AddToLstViewChat(Message newMessage) {
chatMsgList.add(newMessage);
if (chatAdapter == null) {
chatAdapter = new ChatAdapter(getActivity(), chatMsgList);
}
if(IsMsgFromMe(newMessage)) {
lstViewChat = (ListView)
getView().findViewById(R.id.listView_chat_message_me);
} else {
lstViewChat =
(ListView)getView().findViewById(R.id.listView_chat_message_others);
}
chatAdapter.notifyDataSetChanged();
lstViewChat.setAdapter(chatAdapter);
}
ChatActivity:
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
finish();
}
}
For all the code click on the link: "http://pastebin.com/97nR68Rm"
SOLUTION!
Kato thank you for you patience and help. I have now found a solution for the problem. I'm calling ReadGroupData() and ReadChatMessages() at the end (before return) in my onCreateView methods. As Kato pointed out onCreate() is not getting called on popBackStack()
In my AddToLStViewGroup the if statement for lstViewGroup is deleted so now it always sets the listView otherwise it will throw an exception for not finding the correct view, To clarifying:
Deleted this line:
if (lstViewGroup == null) {
lstViewGroup = (ListView)getView().findViewById(R.id.listView_group);
}
And replaced with:
ListView lstViewGroup=(ListView)getView().findViewById(R.id.listView_group);
Kato thank you for you patience and help. I have now found a solution for the problem. I'm calling ReadGroupData() and ReadChatMessages() at the end (before return) in my onCreateView methods. As Kato pointed out onCreate() is not getting called on popBackStack()
In my AddToLStViewGroup the if statement for listViewGroup is deleted so now it always sets the listView otherwise it will throw an exception for not finding the correct view.
To clarify:
I deleted this line:
if (lstViewGroup == null) {
lstViewGroup = (ListView)getView().findViewById(R.id.listView_group);
}
And replaced it with:
ListView lstViewGroup =(ListView)getView().findViewById(R.id.listView_group);
(The original asker posted the answer as part of the question. I'm copying it here as a matter of housekeeping.)

Roman Nurik's Wizard pager - how to access collected data?

I am trying to make a wizard using Roman Nurik's library (https://plus.google.com/113735310430199015092/posts/6cVymZvn3f4).
I am having trouble accessing the collected data from the Review Fragment.
I made mCurrentReviewItems public in ReviewFragment and then I tried it like this
mNextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mPager.getCurrentItem() == mCurrentPageSequence.size()) {
ReviewFragment reviewFragment = (ReviewFragment) mPagerAdapter.getItem(mPager.getCurrentItem());
for (ReviewItem item : reviewFragment.mCurrentReviewItems)
Log.d(MainActivity.TAG, "Item: " + item.getDisplayValue());
}
} else {
if (mEditingAfterReview) {
mPager.setCurrentItem(mPagerAdapter.getCount() - 1);
} else {
mPager.setCurrentItem(mPager.getCurrentItem() + 1);
}
}
}
});
However its always null.
Inside if (mPager.getCurrentItem() == mCurrentPageSequence.size()) { }
For single page variable:
String data = mWizardModel.findByKey("Sandwich:Bread").getData().getString(Page.SIMPLE_DATA_KEY);
For customized page:
String data =
mWizardModel.findByKey(THE_KEY).getData().getString(CustomerInfoPage.YOUR_DATA_KEY);
If you want to assign the data back to the wizard, put this at the end of onCreate in FragmentActivity:
Bundle data = new Bundle();
if (!TextUtils.isEmpty(DATA_STRING)) {
data.putString(Page.SIMPLE_DATA_KEY, DATA_STRING);
mWizardModel.findByKey("Sandwich:Bread"").resetData(data);
}
The key "Sandwich:Bread" is from the example, change whatever suit you. Never try the multi one, I think it is more or less the same.
Sorry for big delay, but I think that someone will found this info useful. I found a way to get all ReviewItems since you can have a lot of branches and you won't be able to use the first answer.
I'm pretty sure, that your mPagerAdapter::getItem code looked like in example (so it just returned new fragment, instead of returning current pager fragment). You have to use instantiateItem to get reference on your ReviewFragment.
Object o = mPager.getAdapter().instantiateItem(mPager, mPager.getCurrentItem());
if(o instanceof ReviewFragment) {
List<ReviewItem> items = ((ReviewFragment) o).getCurrentReviewItems();
if(items != null) {
Log.v(TAG, "Items are: " + items.toString());
}
}
This is my code #Anton_Shkurenko
mNextButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mPager.getCurrentItem() == mCurrentPageSequence.size()) {
Object o = mPager.getAdapter().instantiateItem(mPager, mPager.getCurrentItem());
if(o instanceof ReviewFragment) {
List<ReviewItem> items = ((ReviewFragment) o).getCurrentReviewItems();
if(items != null) {
Log.v(TAG, "Items are: " + items.toString());
}
}
}
}
});
The best solution is to include this library in your project as module, and implement your own method for getting review items in ReviewFragment.
public List<ReviewItem> getReviewItems() {
return mCurrentReviewItems;
}
I am not sure why developer did not add that. It's the most important thing in project. Choose items and DO something with them.
Anyone still looking for a solution for this issue you can use following code
ArrayList<ReviewItem> reviewItems = new ArrayList<ReviewItem>();
for (Page page : mWizardModel.getCurrentPageSequence()) {
page.getReviewItems(reviewItems);
}

Categories

Resources