Display ImagesViews with animation issue - java

I want to display ImageViews in GridView using animation. I can display them and apply animation correctly.
But issue is that, if I apply animation on ImageView1 and then to ImageView2 (before animation on ImageView1 is ended) then animation on ImageView1 gets interrupted and ImageView1 is directly set to final state.
Note that I download image using ThreadPoolExecutor with 2 threads. Whenever an image is done downloading, I call addImage(image) method of below ImageAdapter which in turn adds image in GridView and GridView is refreshed to display latest set of images. And Here, while rendering, new image is displayed with animation and this animation(I guess) interrupts animation of currently animating images.
ImageAdapter :
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<Bitmap> images;
private ArrayList<Integer> colors;
private boolean[] alreadyLoadedIndexes;
Animation animation;
AnimatorSet animator;
public void addImage(Bitmap img) {
images.add(img);
notifyDataSetChanged();
}
public void setAnimation(Animation animation) {
this.animator = null;
this.animation = animation;
}
public void setAnimator(AnimatorSet animation) {
this.animation = null;
this.animator = animation;
}
public void resetImages() {
images.clear();
notifyDataSetChanged();
alreadyLoadedIndexes = null;
alreadyLoadedIndexes = new boolean[20];
}
// Constructor
public ImageAdapter(Context c) {
mContext = c;
images = new ArrayList<Bitmap>();
colors = new ArrayList<Integer>();
colors.add(Color.CYAN);
colors.add(Color.BLUE);
colors.add(Color.GRAY);
colors.add(Color.YELLOW);
colors.add(Color.MAGENTA);
alreadyLoadedIndexes = new boolean[20];
}
#Override
public int getCount() {
return 20;
}
#Override
public Object getItem(int position) {
return 20;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView
.setBackgroundColor(colors.get((int) ((Math.sqrt(position) + 2 * position) % 5)));
// If image at index 'position' is available
if (images.size() > position) {
// If loading this image first time then only apply animation
if (!alreadyLoadedIndexes[position]) {
// If animation is specified
if (this.animation != null) {
imageView.setImageBitmap(images.get(position));
imageView.startAnimation(animation);
}
// If animator set is specified
else if (this.animator != null) {
imageView.setImageBitmap(null);
imageView.setBackgroundColor(colors.get((int) ((Math
.sqrt(position) + 2 * position) % 5)));
animator.setTarget(imageView);
animator.start();
Log.e("", "setting image after " + animator.getDuration()
/ 2);
new Handler().postDelayed(
new runnable(imageView, images.get(position)), 500);
} else {
// Use default animation if nothing is specified.
imageView.setImageBitmap(images.get(position));
animation = AnimationUtils.loadAnimation(mContext,
R.anim.fade_in);
imageView.startAnimation(animation);
}
} else {
imageView.setImageBitmap(images.get(position));
}
alreadyLoadedIndexes[position] = true;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
return imageView;
}
class runnable implements Runnable {
ImageView image;
Bitmap bitmap;
public runnable(ImageView img, Bitmap bitmap) {
this.image = img;
this.bitmap = bitmap;
}
#Override
public void run() {
Log.e("", "setting image.");
image.setImageBitmap(bitmap);
}
}
}

try layout animation controlor for GridView, it will animate the views item by item with respect to time duration. check this link ,

Have you tried to apply the animation outside adapter getView method like:
mGridView.getChildAt(childIndexNeededToAnimate).startAnimation(animation);
These child views are independent and not being recycled anymore since they are already drawn.

You have some alternative.
First you can use Animation in your adapter class if you don't want to change your code.
For that check this.
In your adapter class inside the getView you have to call animation like this ,
Animation animation = null;
animation = AnimationUtils.loadAnimation(context, R.anim.push_left_in);
animation.setDuration(500);
convertView.startAnimation(animation);
return convertView;
Second you should use GridLayoutAnimationController in which A layout animation controller is used to animated a grid layout's children.
Sample 1
Sample 2

Just a guess. I'm neither sure if it will help nor if I read your code right. I suppose the problem is harder than I guess.
However, you are using the same animation object for every item. Maybe you should create a new animation for each item. This could be the reason why your animation stops when you launch a new one because the new call just reuse and restarts it.
Good luck.

You problem is notifyDataSetChanged(); it interrupt the animation. Try calling it when the animation is finished.

Related

How can I fingerpaint with touch over an image loaded by picasso

I am creating an app that pulls images from urls and puts them into a recyclerview. The user can then access those images and view it fullscreen. This is achieved with Picasso. I would now like the ability to fingerpaint over the image loaded with Picasso with an onTouchEvent or something but not sure how to do it.
This class sets the image to a map_edit_gallery.xml loaded with Picasso:
public class EditMapImage extends AppCompatActivity {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_edit_gallery);
checkIntent();
//Find savebutton
ImageButton saveMapButton = findViewById(R.id.saveEditImagebutton);
saveMapButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),"Saved",Toast.LENGTH_SHORT).show();
}
});
}
//This will check to see if the intent extras exist and if they do get the extra
private void checkIntent(){
if(getIntent().hasExtra("image_url") && getIntent().hasExtra("name_url")){
String imageUrl = getIntent().getStringExtra("image_url");
String nameUrl = getIntent().getStringExtra("name_url");
setMapImage(imageUrl, nameUrl);
}
}
private void setMapImage(String imageUrl, String nameUrl){
//Set the Text view
TextView name = findViewById(R.id.mapNameEditor);
name.setText(nameUrl);
//Set the Image
ImageView imageView = findViewById(R.id.mapEditScreen);
Picasso.get().load(imageUrl).into(imageView);
Picasso picasso = Picasso.get();
DrawToImage myTransformation = new DrawToImage();
picasso.load(imageUrl).transform(myTransformation).into(imageView);
}
}
EDIT:
This class has allowed me to draw over the loaded image using canvas but cannot figure out how to use touch to draw:
public class DrawToImage implements Transformation {
#Override
public String key() {
// TODO Auto-generated method stub
return "drawline";
}
public Bitmap transform(Bitmap bitmap) {
// TODO Auto-generated method stub
synchronized (DrawToImage.class) {
if(bitmap == null) {
return null;
}
Bitmap resultBitmap = bitmap.copy(bitmap.getConfig(), true);
Canvas canvas = new Canvas(resultBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
canvas.drawLine(0, resultBitmap.getHeight()/2, resultBitmap.getWidth(), resultBitmap.getHeight()/2, paint);
bitmap.recycle();
return resultBitmap;
}
}
}
Try using the image selected by the user to set it in a canvas object and draw on the canvas object itself, as opposed to the image. There are plenty of tutorials out there to help you with how to draw on a canvas.
This process isn't connected with the Picasso Image Library in any way so I would recommend first getting the image through Picasso, then sending the image into your custom canvas implementation, then returning a bitmap/drawable which you could set into Picasso after editing.
There's also plenty of tutorials on how to export an image from the canvas to get your edited image when you need it.
I hope this helped, Panos.

Text Size Change in Adapter class updates text size in all activities

The following is my WordAdapter class
public class WordAdapter extends ArrayAdapter<Word> {
/** Resource ID for the background color for this list of words */
private int mColorResourceId;
/**
* Create a new {#link WordAdapter} object.
*
* #param context is the current context (i.e. Activity) that the adapter is being created in.
* #param words is the list of {#link Word}s to be displayed.
* #param colorResourceId is the resource ID for the background color for this list of words
*/
public WordAdapter(Context context, ArrayList<Word> words, int colorResourceId) {
super(context, 0, words);
mColorResourceId = colorResourceId;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// Check if an existing view is being reused, otherwise inflate the view
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
// Get the {#link Word} object located at this position in the list
final Word currentWord = getItem(position);
// Find the TextView in the list_item.xml layout with the ID miwok_text_view.
TextView miwokTextView = (TextView) listItemView.findViewById(R.id.miwok_text_view);
// Get the Miwok translation from the currentWord object and set this text on
// the Miwok TextView.
miwokTextView.setText(currentWord.getMiwokTranslationId());
// Find the TextView in the list_item.xml layout with the ID default_text_view.
TextView defaultTextView = (TextView) listItemView.findViewById(R.id.default_text_view);
// Get the default translation from the currentWord object and set this text on
// the default TextView.
defaultTextView.setText(currentWord.getDefaultTranslationId());
TextView onClickTextView = (TextView) listItemView.findViewById(R.id.miwok_text_view_on_click);
onClickTextView.setText((currentWord.getTextOnClickId()));
final ImageView playIcon = (ImageView) listItemView.findViewById(R.id.play_icon);
final ImageView playIconPlaying = (ImageView) listItemView.findViewById(R.id.play_icon_playing);
// Find the ImageView in the list_item.xml layout with the ID image.
final ImageView imageView = (ImageView) listItemView.findViewById(R.id.image);
// Check if an image is provided for this word or not
if (currentWord.hasImage()) {
// If an image is available, display the provided image based on the resource ID
imageView.setImageResource(currentWord.getImageResourceId());
// Make sure the view is visible
imageView.setVisibility(View.VISIBLE);
} else {
// Otherwise hide the ImageView (set visibility to GONE)
imageView.setVisibility(View.GONE);
}
if (Activity1.isActive == true){
onClickTextView.setTextSize(55);
} else {
onClickTextView.setTextSize(35);
}
if (Activity3.isActive == true){
onClickTextView.setTextSize(55);
} else {
onClickTextView.setTextSize(35);
}
// add a tag to determine the position of the view, when the view is clicked.
imageView.setTag(position);
// Set the theme color for the list item
View textContainer = listItemView.findViewById(R.id.text_container);
// Find the color that the resource ID maps to
int color = ContextCompat.getColor(getContext(), mColorResourceId);
// Set the background color of the text container View
textContainer.setBackgroundColor(color);
// Return the whole list item layout (containing 2 TextViews) so that it can be shown in
// the ListView.
// ImageView imageView = (ImageView) listItemView.findViewById(R.id.list_item);
imageView.setOnClickListener(new ImageView.OnClickListener() {
#Override
public void onClick(View view) {
if(currentWord.isFlag){
currentWord.isFlag = false;
Word.flaggedPosition = -1;
}else{
if (Word.flaggedPosition >=0) {
Word.adapter.getItem(Word.flaggedPosition).isFlag = false;
}
currentWord.isFlag = true;
Word.flaggedPosition = position;
}
notifyDataSetChanged();
}
});
if(currentWord.isFlag)
{
imageView.setAlpha(60);
onClickTextView.setVisibility(View.VISIBLE);
}
else
{
imageView.setAlpha(255);
onClickTextView.setVisibility(View.INVISIBLE);
}
return listItemView;
}
}
its the onClickTextView TextView is which i wish to change in Activities...
the activity2 has no change in the textView size which is 35sp
the following is my VarnamalaFragment class
public class VarnamalaFragment extends Fragment {
/** to check whether Acitivity is Active */
static boolean isActive = true;
/** Stores the last selected position */
private int lastSelectedPosition = -1;
/** Handles playback of all the sound files */
private MediaPlayer mMediaPlayer;
/** Handles audio focus when playing a sound file */
private AudioManager mAudioManager;
// Create a list of words
private ArrayList<Word> words = new ArrayList<Word>();
/**
* This listener gets triggered whenever the audio focus changes
* (i.e., we gain or lose audio focus because of another app or device).
*/
private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
#Override
public void onAudioFocusChange(int focusChange) {
if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT ||
focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
// The AUDIOFOCUS_LOSS_TRANSIENT case means that we've lost audio focus for a
// short amount of time. The AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK case means that
// our app is allowed to continue playing sound but at a lower volume. We'll treat
// both cases the same way because our app is playing short sound files.
// Pause playback and reset player to the start of the file. That way, we can
// play the word from the beginning when we resume playback.
mMediaPlayer.pause();
mMediaPlayer.seekTo(0);
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
// The AUDIOFOCUS_GAIN case means we have regained focus and can resume playback.
mMediaPlayer.start();
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// The AUDIOFOCUS_LOSS case means we've lost audio focus and
// Stop playback and clean up resources
releaseMediaPlayer();
}
}
};
/**
* This listener gets triggered when the {#link MediaPlayer} has completed
* playing the audio file.
*/
private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
// Now that the sound file has finished playing, release the media player resources.
if(lastSelectedPosition != -1){
Word lastWord = words.get(lastSelectedPosition);
lastWord.isPlaying = false;
lastSelectedPosition = -1;
Word.adapter.notifyDataSetChanged();
}
releaseMediaPlayer();
}
};
public VarnamalaFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.word_list, container, false);
// Create and setup the {#link AudioManager} to request audio focus
mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
words.add(new Word(R.string.letter_a, R.string.miwok_letter_a,
R.drawable.a_se_anaar,R.string.miwok_letter_a_only, R.raw.a_se_anaar_audio));
words.add(new Word(R.string.letter_aa, R.string.miwok_letter_Aa,
R.drawable.aa_se_aam, R.string.miwok_letter_Aa_only, R.raw.aa_se_aam_audio));
words.add(new Word(R.string.letter_e, R.string.miwok_letter_E,
R.drawable.e_se_emli,R.string.miwok_letter_E_only, R.raw.e_se_emli_audio));
// Create an {#link WordAdapter}, whose data source is a list of {#link Word}s. The
// adapter knows how to create list items for each item in the list.
Word.adapter = new WordAdapter(getActivity(), words, R.color.category_varnamala_vowels);
// Find the {#link ListView} object in the view hierarchy of the {#link Activity}.
// There should be a {#link ListView} with the view ID called list, which is declared in the
// word_list.xml layout file.
ListView listView = (ListView) rootView.findViewById(R.id.list);
// Make the {#link ListView} use the {#link WordAdapter} we created above, so that the
// {#link ListView} will display list items for each {#link Word} in the list.
listView.setAdapter(Word.adapter);
// Set a click listener to play the audio when the list item is clicked on
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
// Release the media player if it currently exists because we are about to
// play a different sound file
releaseMediaPlayer();
// Get the {#link Word} object at the given position the user clicked on
Word word = words.get(position);
word.isPlaying = true;
if(lastSelectedPosition != -1){
Word lastWord = words.get(lastSelectedPosition);
lastWord.isPlaying = false;
}
lastSelectedPosition = position;
Word.adapter.notifyDataSetChanged();
// Request audio focus so in order to play the audio file. The app needs to play a
// short audio file, so we will request audio focus with a short amount of time
// with AUDIOFOCUS_GAIN_TRANSIENT.
int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// We have audio focus now.
// Create and setup the {#link MediaPlayer} for the audio resource associated
// with the current word
mMediaPlayer = MediaPlayer.create(getActivity(), word.getAudioResourceId());
// Start the audio file
mMediaPlayer.start();
word.isPlaying = true;
Word.adapter.notifyDataSetChanged();
// Get the value of currentVolume
int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
// If currentVolume is set to 0, show Toast
if (currentVolume ==0){
Toast.makeText(getContext(), "Please Turn the Volume Up ", Toast.LENGTH_SHORT).show();
}
// Setup a listener on the media player, so that we can stop and release the
// media player once the sound has finished playing.
mMediaPlayer.setOnCompletionListener(mCompletionListener);
}
}
});
return rootView;
}
#Override
public void onStart() {
super.onStart();
isActive = true;
}
#Override
public void onStop() {
super.onStop();
isActive = false;
// When the activity is stopped, release the media player resources because we won't
// be playing any more sounds.
releaseMediaPlayer();
}
/**
* Clean up the media player by releasing its resources.
*/
private void releaseMediaPlayer() {
// If the media player is not null, then it may be currently playing a sound.
if (mMediaPlayer != null) {
// Regardless of the current state of the media player, release its resources
// because we no longer need it.
mMediaPlayer.release();
// Set the media player back to null. For our code, we've decided that
// setting the media player to null is an easy way to tell that the media player
// is not configured to play an audio file at the moment.
mMediaPlayer = null;
// Regardless of whether or not we were granted audio focus, abandon it. This also
// unregisters the AudioFocusChangeListener so we don't get anymore callbacks.
mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
}
}
}
The problem i face is the app changes the text size to 55sp in all the activities including activity2 for which i have no IF..ELSE block...
How do i change the textSize to 55sp in activity1 and activity3 in my Adapter class
I have logged and checked the logcat for correct updation of the isActive value to true and false when the activity1 and activity3 is active and not active....
In your Case, You can check using class name. Like,
context.getClass().getSimpleName()
which return value "Activity1" .
updated class >>
public class WordAdapter extends ArrayAdapter<Word> {
private int mColorResourceId;
private Context mContext;
public WordAdapter(Context context, ArrayList<Word> words, int colorResourceId) {
super(context, 0, words);
mColorResourceId = colorResourceId;
mContext = context;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
final Word currentWord = getItem(position);
TextView miwokTextView = (TextView) listItemView.findViewById(R.id.miwok_text_view);
miwokTextView.setText(currentWord.getMiwokTranslationId());
TextView defaultTextView = (TextView) listItemView.findViewById(R.id.default_text_view);
defaultTextView.setText(currentWord.getDefaultTranslationId());
TextView onClickTextView = (TextView) listItemView.findViewById(R.id.miwok_text_view_on_click);
onClickTextView.setText((currentWord.getTextOnClickId()));
final ImageView playIcon = (ImageView) listItemView.findViewById(R.id.play_icon);
final ImageView playIconPlaying = (ImageView) listItemView.findViewById(R.id.play_icon_playing);
final ImageView imageView = (ImageView) listItemView.findViewById(R.id.image);
if (currentWord.hasImage()) {
imageView.setImageResource(currentWord.getImageResourceId());
imageView.setVisibility(View.VISIBLE);
} else {
imageView.setVisibility(View.GONE);
}
if (mContext.getClass().getSimpleName().equalsIgnoreCase("Activity1") || mContext.getClass().getSimpleName().equalsIgnoreCase("Activity3")) {
onClickTextView.setTextSize(55);
} else {
onClickTextView.setTextSize(35);
}
imageView.setTag(position);
View textContainer = listItemView.findViewById(R.id.text_container);
int color = ContextCompat.getColor(getContext(), mColorResourceId);
textContainer.setBackgroundColor(color);
imageView.setOnClickListener(new ImageView.OnClickListener() {
#Override
public void onClick(View view) {
if (currentWord.isFlag) {
currentWord.isFlag = false;
Word.flaggedPosition = -1;
} else {
if (Word.flaggedPosition >= 0) {
Word.adapter.getItem(Word.flaggedPosition).isFlag = false;
}
currentWord.isFlag = true;
Word.flaggedPosition = position;
}
notifyDataSetChanged();
}
});
if (currentWord.isFlag) {
imageView.setAlpha(60);
onClickTextView.setVisibility(View.VISIBLE);
} else {
imageView.setAlpha(255);
onClickTextView.setVisibility(View.INVISIBLE);
}
return listItemView;
}
}

Access a certain button from recyclerview and change it's background image

I'm trying to change the background image of a certain button when clicked in a recyclerView. The button's background image is changing properly but also changing the background of the button found in the 8th..16th..etc row as well. (I am currently populating data in the recycler view using a for-loop for testing)
My code is
#Override
public void onBindViewHolder(final myFirstAdapter.ViewHolder holder, int position) {
firstlistitem listItem = listItems.get(position);
holder.itemView.setTag(position);
holder.btnBookMark.setTag(position);
holder.btnBookMark.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.btnBookMark.setBackgroundResource(R.drawable.bookmarkred);
}
});
}
The background is changing because, its a RecyclerView and it recyclers the view and reuses it. Hence, when you click on 8th position and scroll to bottom, it is reusing the item at 8 position with custom background for other items. Because of this you are getting custom background for later items on scroll.
If you have many items which will have changed background do this.
class ViewHolder extends RecyclerView.ViewHolder{
boolean newBackground = false;
Button button
ViewHolder(View itemView){
...
button.setOnClickListner((v) - > newBackground = true);
}
}
Then you can check the value of newBackground and set the background in onBindViewHolder()
If you have only one item of which the background will change at a time then you can declare a field in the Adapter and check that to change the background.
class MyAdapter extends RecyclerView.Adapter<ViewHolder>{
int newBackgroundPos = -1;
#Override
public final void onBindViewHolder(ViewHolder holder, int position) {
holder.button.setOnClickListener((v) -> newBackGroundPos = position);
if(position == newBackgroundPos)
holder.itemView.setBackground(newBackground);
else
holder.itemView.setBackground(normalBackground);
}
}

Resizing Views before drawing

In my layout I have a GridView containing 4 custom ImageViews. I'm setting GridView's visibility to invisible until all ImageViews are resized at first but when the GridView is shown, there's a short blink with ImageViews still unchanged.
blink for a split second
views are resized in a moment
Each ImageView creates separate listener in order to scale its size:
//Setting new params as half of parent's size and increasing counter
if (getViewTreeObserver().isAlive()) {
final ViewTreeObserver viewTreeObserver = getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
getViewTreeObserver().removeOnPreDrawListener(this);
View parent = (View) getParent();
int dimension = Math.min(parent.getWidth(), parent.getHeight()) / 2;
mThisImageView.setLayoutParams(new AbsListView.LayoutParams(dimension, dimension));
ResizeCounter.setCounter(ResizeCounter.getCounter() + 1);
return true;
}
});
}
//Activity listens to the moment when all ImageViews have been resized
ResizeCounter.addCounterListener(new OnResizeCounterChangeListener() {
#Override
public void onResizeCounterChanged() {
if (ResizeCounter.getCounter() == 4) {
mAnswerGridView.setVisibility(View.VISIBLE);
}
}
});
I've also tried to resize them in onGlobalLayout method (same result) and to override onMeasure method (parent View is still null at this point).
I suspect that it's too late to change views in onPreDraw() but is there a method that can be called earlier inside which I can be sure that all views have been measured?
Try to call mAnswerGridView.requestLayout() before mAnswerGridView.setVisibility(View.VISIBLE);
This may not work because as it's stated at Android Developers
This will schedule a layout pass of the view tree.
So you may better force relayout:
relayoutChildren(View view) {
view.measure(
View.MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), View.MeasureSpec.EXACTLY));
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()); }
I've created a handler that schedules setting visibility right after calling requestLayout.
Works well in this case.
ResizeCounter.addCounterListener(new OnResizeCounterChangeListener() {
#Override
public void onResizeCounterChanged() {
if (ResizeCounter.getCounter() == 4) {
mAnswerGridView.requestLayout();
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
mAnswerGridView.setVisibility(View.VISIBLE);
}
});
}
}
});

Picasso loading duplicate images

Ive searched and cant find anything to do with this problem im getting, im loading images into multiple grid views each inside a tabbed page view. Performance is great but any grid view that has lots of images and needs to scroll the images loaded are incorrect, it dublicates images and loads them into the wrong position. Below is one of the adapters im using for the grid view:
public class PcAdapter extends BaseAdapter {
private Context context;
private Integer[] imageIds = {
R.drawable.pcserioussam, R.drawable.pc_trinetwo,
R.drawable.pc_leftfordead, R.drawable.pc_dungeondefenders,
R.drawable.pc_portaltwo, R.drawable.pc_spaz,
R.drawable.pc_laracroftattoo, R.drawable.pc_goatsim,
R.drawable.pc_deadblock, R.drawable.pc_dynasty,
R.drawable.pc_minecraft, R.drawable.pc_kanelynch,
R.drawable.pc_toy, R.drawable.pc_awesomenauts,
R.drawable.pc_bioniccomm, R.drawable.pc_fastandfurious,
R.drawable.gen_harryone, R.drawable.gen_harrytwo,
R.drawable.gen_watchmen
};
public PcAdapter(Context c) {
context = c;
}
public int getCount() {
return imageIds.length;
}
public Object getItem(int position) {
return imageIds[position];
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View view, ViewGroup parent) {
ImageView iview;
if(view == null){
iview = new ImageView(context);
Picasso.with(context).load(imageIds[position]).
placeholder(R.drawable.placeholder).
resize(230, 300).centerInside().into(iview);
} else {
iview = (ImageView) view;
}
return iview;
}
}
Any help with this would be much appreciated
Move your picasso code out of the if statement. Currently it will only load a new image if view is null? Put it at the bottom of the if statement just before the return statement.

Categories

Resources