I have a piece of code that adds / update the content of the card view that resides in a recycler view.
However, it doesn't update the content even though I have called
viewAdapter.notifyItemChanged(position);
and
viewAdapter.notifyItemChanged(position);
I have tried calling it in runOnUiThread method but it still does not update. I tried stepping into onBindViewHolder() and the values are updated inside but the display on the screen just won't get updated.
Any idea why?
Some of my code below:
rvTransactionItems = (RecyclerView) mView.findViewById(R.id.rvTransactionItems);
rvTransactionItems.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getParentActivity());
rvTransactionItems.setLayoutManager(llm);
detailAdapter = new DetailAdapter();
rvTransactionItems.setAdapter(detailAdapter);
#Override
public void onBindViewHolder(DetailViewHolder viewHolder, int i) {
StockCount count = addedItemCount.get(i);
Integer expectedQty = count.getExpectedQuantity();
Integer quantity = count.getQuantity();
viewHolder.tvArticleNumber.setText(articleNumber);
viewHolder.tvStockCode.setText(stockCode);
String countStr = quantity + " / " + expectedQty;
viewHolder.tvCount.setText(countStr);
}
I figured out how to solve my issue. The problem root was that my function calling the handler(protected Handler updateUiHandler = new Handler(Looper.getMainLooper());) that had to notify the adapter was in another thread. So basically I'm trying to run something on the main thread in another thread. So I have to go up the call hierarchy to invoke the method to be runOnUiThread. That will solve the issue.
So in conclusion, the notifyChange method must run on the main thread for the change to be effect!
Related
I am getting a Android.Content.ActivityNotFoundException: when I want to go to another activity.
Also I have to recreate my emulator every time I want to see my app because it causes always adb error the second time I start the emulator.
I read that this can be caused by another exception, but I checked a other code and I didnt find anything
Button btnentrar = FindViewById<Button>(Resource.Id.createlist);
btnentrar.Click += delegate
{
StartActivity(typeof(listeditorclass));
};
//activity:
private List<string> mItems;
private ListView mListView;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.listeditor);
mListView = FindViewById<ListView>(Resource.Id.listView);
mItems = new List<string>();
mItems.Add("Milch");
mItems.Add("Brot");
mItems.Add("Apfel");
MyListViewAdapter adapter = new MyListViewAdapter(this, mItems);
mListView.Adapter = adapter;}
also I dont know the diffrents between AppCompatActivity and a normal activity. So general the user should see when he clicks on the button the new view (createlist) with my list.
I hadn't used anonymous delegates on Xamarin before, that's a cool thing. Try using an intent and passing the Context:
btnentrar.Click += delegate
{
StartActivity(new Intent(this, typeof(listeditorclass)));
};
Can Any one help Me on How to Implement on Handling Pagination on Scrolling of listview in xamarin.android .any link or any sample wil be helpful
Well, Android pagination is quite easy in comparison to iOS and can be done as follows:
public class EndlessScrollListener : Java.Lang.Object, Android.Widget.AbsListView.IOnScrollListener
{
private int visibleThreshold = 5;
private int currentPage = 0;
private int previousTotal = 0;
private bool loading = true;
public EndlessScrollListener()
{
}
public EndlessScrollListener(int visibleThreshold)
{
this.visibleThreshold = visibleThreshold;
}
public void OnScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (loading)
{
if (totalItemCount > previousTotal)
{
loading = false;
previousTotal = totalItemCount;
currentPage++;
}
}
if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))
{
// I load the next page of gigs using a background task,
// but you can call any function here.
//new LoadGigsTask().execute(currentPage + 1);
loading = true;
}
}
public void OnScrollStateChanged(AbsListView view, [GeneratedEnum] ScrollState scrollState)
{
// throw new NotImplementedException();
}
}
Then set it to the listview as follows:
List.SetOnScrollListener(new EndlessScrollListener());
Working of code:
visibleThreshold – The minimum amount of items to have below your current scroll position, before loading more.
currentPage – The current page of data you have loaded.
previousTotal – The total number of items in the dataset after the last load.
loading – True if we are still waiting for the last set of data to load.
Next, we have a couple of constructors that allow us to set the visibleThreshold inline if we want.
The first overridden method we have is called every time the list is scrolled. This happens many times a second during a scroll, so be wary of the code you place here. We are given a few useful parameters to help us work out if we need to load some more data, but first, we check if we are waiting for the previous load to finish.
If it’s still loading, we check to see if the dataset count has changed, if so we conclude it has finished loading and update the current page number and total item count.
If it isn’t currently loading, we check to see if we have breached the visibleThreshold and need to reload more data. If we do need to reload some more data, we execute a background task and set the loading flag to true. Thus solving the problem forever!
The last method in the class we do not need, however, if you’re interested, it is primarily used for tracking changes in the scroll action itself via the scrollState parameter.
Finally, the code to call the class creates a new instance of EndlessScrollListener and bind’s it to a ListView of mine. Of course, put your own ListView in place of List.
I'm trying to add some error handling (to cope with loses of network connectivity when initializing my view models as well as elsewhere) by having it publish a message that is picked up by my view models that will then do a ChangePresentation with a PresentationHint that causes my presenter (derived from MvxTouchViewPresenter) to do this:
this.MasterNavigationController.PopToRootViewController(false);
This occasionally works, but a lot of the time it doesn't, getting stuck on whatever view it was currently on and I see the message Unbalanced calls to begin/end appearance transitions for <MyView: 0x...>. I believe this is because sometimes the message is getting thrown before the view that was loading has had time to finish loading (the actual loading of data is asynchronous and fires up on another thread - hence the problem).
So my question is, is there a way to synchronize this so that instead of immediately popping to the root, it will finish what it's doing, then pop to the root? Or is there some better way to handle this?
There's not quite enough code in your question to work out what's happening. There are lots of other questions on StackOverflow containing that error message - it may be worth looking through them to see if there is a nice solution to your issue. e.g. UINavigationController popToRootViewController, and then immediately push a new view
If you do want to detect 'finish loading' then on way to do this is to listen to the ViewDidAppear messages in the ViewControllers that are being shown. In mvx, this is easy to do as all ViewController's support a ViewDidAppearCalled event that you could easily hook up in your custom presenter:
private readonly Queue<Action> _pendingActions = new Queue<Action>();
private bool _isBusy;
public override void Show(Cirrious.MvvmCross.Touch.Views.IMvxTouchView view)
{
if (_isBusy)
{
_pendingActions.Enqueue(() => Show(view));
return;
}
_isBusy = true;
var eventSource = view as IMvxEventSourceViewController;
eventSource.ViewDidAppearCalled += OnViewAppeared;
base.Show(view);
}
private void OnViewAppeared(object sender, MvxValueEventArgs<bool> mvxValueEventArgs)
{
_isBusy = false;
var eventSource = sender as IMvxEventSourceViewController;
eventSource.ViewDidAppearCalled -= OnViewAppeared;
if (!_pendingActions.Any())
return;
var action = _pendingActions.Dequeue();
action();
}
public override void ChangePresentation(Cirrious.MvvmCross.ViewModels.MvxPresentationHint hint)
{
if (_isBusy)
{
_pendingActions.Enqueue(() => ChangePresentation(hint));
return;
}
base.ChangePresentation(hint);
}
Note: this code requires 3.0.13 or later to work (there was a bug for ViewDidAppear in some view controllers in earlier versions)
If you are using a simple UINavigationController, another way to achieve a similar effect is to use the Delegate on that controller - see https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationControllerDelegate_Protocol/Reference/Reference.html
For the GUI portion of my app, how could I update the RichTextField when my batteryStatusChange method is invoked that changes on the spot?
I was thinking of calling a set method and then having RichTextField get that new number, but it will make a long list of lines unless I delete the textfield before I add a new one.
Something like the battery percentage number under Device Information or the signal strength that changes on the spot.
Edit: Figured it out using setText
public void batteryStatusChange(int status)
{
// TODO Auto-generated method stub
if ((status & DeviceInfo.BSTAT_LEVEL_CHANGED) != 0)
{
batteryStatusField.setText(getBatteryLevel());
}
}
batteryStatusField.setText(getBatteryLevel());
public String getBatteryLevel() {
return Integer.toString(DeviceInfo.getBatteryLevel()) + " %";
}
Got it to work with this code above by putting it inside my batteryStatusChange listener function. Later I will add in more parameters after the function getBatteryLevel() to keep my default formatting.
My battery app in progress
I have a scroll bar ( fl.controls.UIScrollBar ), which i create dynamically in a class, and add it to the stage.
public class Slider extends Sprite
{
private var scroll:UIScrollBar = new UIScrollBar();
// etc.
// constructor
addChild(scroll);
scroll.setSize(15.75, 205.3);
scroll.direction = ScrollBarDirection.HORIZONTAL;
scroll.setScrollProperties(150, minScrollPos, maxScrollPos,snapInterval);
scroll.addEventListener(ScrollEvent.SCROLL, scrollHandler);
}
Then, I try to call
scroll.scrollPosition = 30;
My method call will not update the scroll thumb.Any ideas why?
Salut Mihai,
I found that odd at first. I expected setting the value would suffice.
If I set scrollPosition in an enter frame loop, it works, but not if I use the setter straight away. This probably means that if you make the calls right after creating/setting up the component, internally, it's not ready yet. UIComponents(like UIScrollBar) have a whole lifecycle to deal with. Jeff Kamerer has a nice set of devnet articles on this, if you're interested.
Long story short, the component is not ready right away, so the best bet is to wait for it to be ready by listening to the RENDER event:
scroll.addEventListener(Event.RENDER,rendered);
function rendered(event:Event):void {
scroll.removeEventListener(Event.RENDER,rendered);
scroll.scrollPosition = 30;
}