Android - Access child of gridview that is not on screen - android

Is it possible to access a child view of a gridview that is not on screen and change it?
I have tried using getCount() when iterating over the gridview, but when it reaches the children that are not visible(on screen display) they lose their type (they should be ImageViews) and I can not do anything with them; I want to change their image.
An snippet of code;
GridView gridView = (GridView) findViewById(R.id.grid_view);
Integer items = gridView.getCount();
Log.d(TAG, "1)child count::"+((ViewGroup)gridView).getChildCount());
Log.d(TAG, "2)get count::"+items);
for (int i=0; i < items; ++i) {
View nextChild = ((ViewGroup)gridView).getChildAt(i);
if (nextChild instanceof ImageView) {
Log.i(TAG, i+" is imageview");
((ImageView) nextChild).setImageResource(R.drawable.arrow2);
} else {
Log.i(TAG, i+" is NOT imageview");
}
}

You should be setting the image resource in the adapter's getView() method. Then the code will run as and when they become visible, rather than trying to force it before they come into the screen.

Related

Alternative to adding dynamic view inside of a ViewHolder RecyclerView Adapter

I am currently adding ImageViews and setting the images within a ViewHolder. The creation time is not smooth and the first scroll through is not smooth either. Any suggestion or an alternative to having smooth dynamic views within a viewholder?
ViewHolder
class ViewHolderRecipientExpanded extends RecyclerView.ViewHolder {
private LinearLayout mFlagLayout;
//
public ViewHolderRecipientExpanded(View v) {
super(v);
mFlagLayout = (LinearLayout) v.findViewById(R.id.flagLayout);
//
}
public void initiateRecipientsDetails() {
Recipient recipient = objectList.get(getAdapterPosition());
int totalAmountOfCountries = recipient.getFlags() != null ? recipient.getFlags().size() : 0;
//
int countriesLimitedToThree = recipient.getFlags() != null ? (totalAmountOfCountries > 3 ? 3 : totalAmountOfCountries) : 0;
View imageView;
ImageView image;
Drawable drawable;
for (int i = 0; i < countriesLimitedToThree; i++) {
imageView = inflater.inflate(R.layout.view_image_flag, null);
image = (ImageView) imageView.findViewById(R.id.image);
drawable = new BitmapDrawable(context.getResources(), recipient.getFlags().get(i).getFlag());
image.setImageDrawable(drawable);
mFlagLayout.addView(imageView);
}
}
}
Load your images asynchronously, and cache them in memory when they are not in view. This will not block the UI thread when loading images, allowing the user to scroll even if the images aren't loaded yet. Though, it will still take some time for the images to actually appear.
There are also a number of great libraries that will handle this for you:
Picasso
Glide
Fresco

Get Tags in a GridView

I have a gridview called grid where I'm displaying random coloured circles that the user can change, each view inside the grid is tagged according to the colour of circle that is inside it. I have no problem getting the tag when the user clicks on a view but I'm now needing to be able to go through the whole grid and count how many of the circles are a certain colour, here is my code I have tried, this gives me a null pointer exception:
public void targCheck(){
targNum = 0;
int pos = 0;
for (int i = 0; i < gridSize; i++){
View v = grid.getChildAt(pos);
obj = (Integer) v.getTag(); //this is whats causing the problem
if (obj == target){
targNum += 1;
test.setText(targNum.toString());
}
pos += 1;
}
}
I think I might need to use the Image adapter to get the tags but I'm not sure how to use it in a method like this.

How to setImageResource of a dynamically declared ImageButtons?

I have some dynamically declared ImageButtons, these ImageButtons don't have ids' and they are declared in a LinearLayout, I want to create a method to change Images resources of these ImageButtons when called, and as I don't have a predefined ids' for these ImageButtons I'm using the function getChildAt() with the LinearLayout, but getChildAt() doesn't provide setImageResource(), it just provide setBackgroundResource() and this function doesn't make a replacement to the old Image and also doesn't fit at the old Image as it provides a background not an Image Resource, what can I do with that ?
this is my method code :
private void my_method(int drawable) {
int count = Righter.getChildCount(); // Righter is the LinearLayout
for (int i = 1; i < count; i++) {
Righter.getChildAt(i).setBackgroundResource(drawable); // here is where i change the background image
Righter.getChildAt(i).setClickable(true);
}
}
getChildAt() returns View. you need to typecast this View to ImageButton and call setImageResource() method...
ImageButton imageButton = (ImageButton) linearLayout.getChildAt(0);
imageButton.setImageResource(R.drawable.btnimage1);
try this
private void my_method(int drawable) {
int count = Righter.getChildCount(); // Righter is the LinearLayout
for (int i = 1; i < count; i++) {
((ImageButton)Righter.getChildAt(i)).setImageResource(R.drawable.btnimage1);
Righter.getChildAt(i).setClickable(true);
}
}
type cast you Righter.getChildAt(i) with ImageButton

Android only download images that are visible in horizontalScrollView

I have a HorizontalScrollView which contains a LinearLayout to hold all my view. I add about 20 RelativeLayout which contains a ImageView and TextView to the LinearLayout. I would like to only load images if the ImageView is on the screen (as I scroll to the ImageView).
I tried following this post to use getHitRect(), on the thumbnail, however, the Rect (bounds) for the thumbnail is always 0, 0-0, 0, resulting in my method to return false. What am I doing wrong?
thumbnailLayout is my LinearLayout inside the HorizontalScrollView
thumbnailScroll is my HorizontalScrollView
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.e(TAG, "running");
for (int i = 0; i < thumbnailLayout.getChildCount(); i++) {
RelativeLayout view = (RelativeLayout) thumbnailLayout.getChildAt(i);
ImageView thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
if (thumbnailIsOnScreen(thumbnail)) {
Log.e(TAG, items.get(i).getTitle() + " has downloaded");
app.setImage(items.get(i).getThumbnailSmall(), thumbnail);
}
}
}
});
private boolean thumbnailIsOnScreen(ImageView thumbnail) {
Rect bounds = new Rect();
thumbnail.getHitRect(bounds);
Rect scrollBounds = new Rect(thumbnailScroll.getScrollX(), thumbnailScroll.getScrollY(),
thumbnailScroll.getScrollX() + thumbnailScroll.getWidth(), thumbnailScroll.getScrollY()
+ thumbnailScroll.getHeight());
return Rect.intersects(scrollBounds, bounds);
}
Edit
I'm tred using TreeObserver and found that my method to check if the thumbails are on screen is wrong. It still grabs all the images, and constantly loops (because I'm using onPreDrawListener?)
thumbnailLayout.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
#Override
public boolean onPreDraw() {
Log.e(TAG, "running");
for (int i = 0; i < thumbnailLayout.getChildCount(); i++) {
RelativeLayout view = (RelativeLayout) thumbnailLayout.getChildAt(i);
ImageView thumbnail = (ImageView) view.findViewById(R.id.thumbnail);
if (thumbnailIsOnScreen(thumbnail)) {
Log.e(TAG, items.get(i).getTitle() + " has downloaded");
app.setImage(items.get(i).getThumbnailSmall(), thumbnail);
}
}
return true;
}
});
Have you thought about using ViewPager?
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
If that doesn't fit your design you need to override the ScrollView -> function onScrollChanged and there check if your image in screen check the image (left?) position compared to the scroll position.
You need a ListView but there isn't native HorizontallListView in android. You can try HorizontallListView by DevSmart. It's works like a native list view, with adapters and custom views if you want.

How do I set the alpha of all items in a listview?

As I am developing for API level 7 and upwards setAlpha(float) is unavailable to me. As such I have implemented a method that traverses all child elements of a given ViewGroup and tries to find a way to set the alpha so that the element is almost transparent. Unfortunately I cannot come up with a way to make the ListView and its items transparent. How do I proceed?
My method:
public void enableDisableViewGroup(ViewGroup viewGroup, boolean enabled) {
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View view = viewGroup.getChildAt(i);
view.setEnabled(enabled);
if (!enabled) {
if (view instanceof TextView) {
int curColor = ((TextView) view).getCurrentTextColor();
int myColor = Color.argb(ALPHA_NUM, Color.red(curColor),
Color.green(curColor),
Color.blue(curColor));
((TextView) view).setTextColor(myColor);
} else if (view instanceof ImageView) {
((ImageView) view).setAlpha(ALPHA_NUM);
} else if (view instanceof ListView) {
// How do I set the text color of the subitems in this listview?
} else {
try {
Paint currentBackgroundPaint =
((PaintDrawable) view.getBackground()).getPaint();
int curColor = currentBackgroundPaint.getColor();
int myColor = Color.argb(ALPHA_NUM, Color.red(curColor),
Color.green(curColor), Color.blue(curColor));
view.setBackgroundColor(myColor);
} catch (NullPointerException e) {
Log.d("viewNotFound", "View " + view.getId() + " not found..");
e.getStackTrace();
}
}
if (view instanceof ViewGroup) {
enableDisableViewGroup((ViewGroup) view, enabled);
}
}
}
}
Is it an option to set this directly in the XML for your ListView row?
For example, if your layout is a LinearLayout
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<!-- stuff -->
</LinearLayout>
I'm not sure of your setup, but you may be able to set it programatically like this if you really want your ListView to be transparent.
ListView listView = (ListView) view;
listView.setBackgroundColor(android.R.color.transparent);
where default color android.R.color.transparent equals:
<!-- Fully transparent, equivalent to 0x00000000 -->
<color name="transparent">#00000000</color>
In this case, you'll need to set your ListView rows to be transparent in the XML anyway.
If you want to control the transparency of the Views inside your ListView rows, your best bet is to create a custom ArrayAdapter and handle this there.

Categories

Resources