How to receive notification from a GridView when it refreshes? - android

A GridView has BaseAdapter derived class responsible for populating its children. It works fine.
I want to do something when the GridView is refreshed. In other words, I wish there was a method "addOnRefreshListner()".
It needs to accommodate API Level as low as 8 (Froyo).

What if you override BaseAdapter.notifyDataSetChanged() in your custom adapter?
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
// A change has happened and caused the GridView to refresh
}

notifyDataSetChanged() is the solution to the absence of your addOnRefreshListener().

Try implementing a View.OnLayoutChangeListener() for API 11 or higher.
View myView = findViewById(R.id.my_view);
myView.addOnLayoutChangedListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
// Do what you need to do with the height/width since they are now set
}
});

Related

how to listen on ImageView VisibiltyChanged

I'm trying to do something once the setVisibility function finish it's work, is there anyway that I can accomplish that? because OnSystemUiVisibilityChangeListener isn't what I need , and I can't find any method that allows me to!
As see here:
ViewTreeObserver.html#addOnGlobalLayoutListener:
Register a callback to be invoked when the global layout state or the
visibility of views within the view tree changes
So you can do it by adding addOnGlobalLayoutListener to ImageView like:
imageView.setTag(imageView.getVisibility());
....
#Override
public void onGlobalLayout() {
int visibility = imageView.getVisibility();
if(Integer.parseInt(imageView.getTag()) != visibility)
{
// visibility changes...
}
}
....
You can try this one it will get triggered every time your layout changes
imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.e("PRACTICE","VISIBILITY IS CHANGED");
}
});

When Have All The Views In A Fragment Been Given A Size?

Without resorting to the infamous onGlobalLayoutListener() solution, and without having to implement a custom View, what lifecycle event in a Fragment can I put code into and be sure all of the Fragment's Views have been given a size?
As a corollary, I would also like this lifecycle event to be applicable to Fragments in a ViewPager.
I dont think there would be any Fragment lifecycle event to be sure all the Views have size.
What I would usually do is, to use OnLayoutChangeListener inside onActivityCreated(). Like this,
getView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
getView().removeOnLayoutChangeListener(this);
// Check the size of Views here.
}
});

rootView Height and Width in Xamarin.Android

I am trying to get a screen capture in the Xamarin.Android platform.
public static Android.Content.Context Context { get; private set; }
public override View OnCreateView(View parent, string name, Context context, IAttributeSet attrs)
{
MainActivity.Context = context;
return base.OnCreateView(parent, name, context, attrs);
}
I am trying to find out the why the following rootView.Width and Height returns 0 all the time.
var rootView = ((Activity)MainActivity.Context).Window.DecorView.RootView;
Console.WriteLine ("{0}x{1}", rootView.Width,rootView.Height);
My ultimate goal is to capture the screenshot of the view as an image and generate pdf.
I don't know Xamarin, however it seems to be the same as native Android for this solution.
When onCreateView() is called the views have not yet been measured. To get a view dimensions you should attach a specific listener: onLayoutChangeListener.
Here is an Android native code example:
rootView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
int oldRight, int oldBottom) {
int width = right - left;
int height = bottom - top;
v.removeOnLayoutChangeListener(this); // Remove the listener
}
});
You could find here the listener to use for Xamarin
Hope its help ! :)
In the onCreateView the width & height of objects are not yet defined. They are defined in a later stage of the activity's lifecycle.
You have to use the treeviewobserver for this.
Example with your rootview:
rootView.ViewTreeObserver.GlobalLayout += (object sender, EventArgs e) => {
Console.WriteLine ("{0}x{1}", rootView.Width,rootView.Height);
};
In that method the width & height will be known.
Furthermore, you want to take a picture of the your rootview, the best way to do this is to use this method, this will automatically output a Bitmap of the view to variable b.
rootView.DrawingCacheEnabled = true;
Bitmap b = rootView.GetDrawingCache(true);
Hope this gets you on your way!

Understanding When ListView Views actually get redrawn after calling notifyDataSetChanged()

From my understanding, there's no API for developers to determine when AdapterView's are getting redrawn.
We call notifyDataSetChanged() and then, at some point in the future, with no event for us to listen for, the ListView redraws it's views.
I say this because I've encountered a situation where I am updating images in a ListView when the scroll has stopped.
Every time I set a new list source - i.e. call notifyDataSetChanged() from my adapter, I then call my updateImagesInView() method - kind of like this:
//MyListView.java
public void setDataSource(SomeClass dataSource) {
((MyListAdapter)myListView.getAdapter()).setSomeDataSource(dataSource);
updateImagesInView();
}
public void updateImagesInView() {
for (int i = 0; i <= mListView.getLastVisiblePosition() - mListView.getFirstVisiblePosition(); i++) {
View listItemView = mListView.getChildAt(i);
...
}
}
//MyListAdapater.java
public void setSomeDataSource(SomeClass dataSource) {
mDataSource = dataSource;
notifyDataSetChanged();
}
The child views I get from the loop in the updateImagesInView method always belong to the previous dataSource.
I've hacked in a workaround, so I'm not looking for a "how to do this" answer, but more along the lines of - is there anyway to know when the views in a ListView have actually been updated after calling notifyDataSetChanged()? (or am I just doing something crazy wrong because the views should effectively be updated immediately after calling notifyDataSetChanged()?)
Well you can add a listener to yourListView's layout like:
mListView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
mListView.removeOnLayoutChangeListener(this);
Log.e(TAG, "updated");
}
});
mAdapter.notifyDataSetChanged();
Otherwise you should listen on your adapter, as when notifyDataSetChanged is called, your adapter gets calls to getView() to update all the views that are currently visible.

Android - Listener for catching changes in a View's properties (e.g. android:layout_marginTop)

In Android, can you create a Listener for catching changes in a View's properties (width / height / margin / position relative to top of the screen)?
I want to trigger an event when layout_marginTop="10dp" is changed to a different value.
What about implementing a OnLayoutChangeListener that gets called when a View is moved due to Layout Change
new View().addOnLayoutChangeListener(new OnLayoutChangeListener() {
#Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
// TODO Auto-generated method stub
}
});
Excerpt from Android API:
Add a
listener that will be called when the bounds of the view change due to
layout processing.

Categories

Resources