improved image loading, bug fix
This commit is contained in:
parent
d91c892275
commit
b412c2e802
|
@ -4,79 +4,132 @@ import android.graphics.Bitmap;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout.LayoutParams;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.widget.ListPopupWindow.MATCH_PARENT;
|
||||
import static android.widget.ListPopupWindow.WRAP_CONTENT;
|
||||
|
||||
|
||||
public class ImageAdapter extends Adapter<ImageAdapter.ImageHolder> {
|
||||
|
||||
private static final int PICTURE = 0;
|
||||
private static final int LOADING = 1;
|
||||
|
||||
private WeakReference<OnImageClickListener> itemClickListener;
|
||||
private Bitmap[] images;
|
||||
private List<Bitmap> images;
|
||||
private boolean loading;
|
||||
|
||||
|
||||
public ImageAdapter(OnImageClickListener l) {
|
||||
itemClickListener = new WeakReference<>(l);
|
||||
images = new Bitmap[0];
|
||||
images = new LinkedList<>();
|
||||
loading = true;
|
||||
}
|
||||
|
||||
|
||||
public void setImages(@NonNull Bitmap[] images) {
|
||||
this.images = images;
|
||||
public void addLast(@NonNull Bitmap image) {
|
||||
int imagePos = images.size();
|
||||
images.add(image);
|
||||
notifyItemInserted(imagePos);
|
||||
}
|
||||
|
||||
|
||||
public Bitmap top() {
|
||||
return images.get(0);
|
||||
}
|
||||
|
||||
|
||||
public void disableLoading() {
|
||||
int circlePos = images.size();
|
||||
loading = false;
|
||||
notifyItemRemoved(circlePos);
|
||||
}
|
||||
|
||||
|
||||
public boolean isEmpty() {
|
||||
return images.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (loading && position == images.size())
|
||||
return LOADING;
|
||||
return PICTURE;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return images.length;
|
||||
if (loading)
|
||||
return images.size() + 1;
|
||||
return images.size();
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ImageAdapter.ImageHolder onCreateViewHolder(@NonNull final ViewGroup parent, int viewType) {
|
||||
ImageView imageView = new ImageView(parent.getContext());
|
||||
return new ImageHolder(imageView);
|
||||
if (viewType == LOADING) {
|
||||
ProgressBar circle = new ProgressBar(parent.getContext());
|
||||
LayoutParams param = new LayoutParams(WRAP_CONTENT, MATCH_PARENT);
|
||||
circle.setLayoutParams(param);
|
||||
return new ImageHolder(circle);
|
||||
} else {
|
||||
return new ImageHolder(new ImageView(parent.getContext()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final ImageAdapter.ImageHolder vh, int index) {
|
||||
final Bitmap image = images[index];
|
||||
public void onBindViewHolder(@NonNull ImageAdapter.ImageHolder vh, int index) {
|
||||
if (vh.view instanceof ImageView) {
|
||||
final Bitmap image = images.get(index);
|
||||
ImageView imageView = (ImageView) vh.view;
|
||||
imageView.setImageBitmap(downscale(image));
|
||||
imageView.setBackgroundColor(0xffffffff);
|
||||
imageView.setPadding(1, 1, 1, 1);
|
||||
imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (itemClickListener.get() != null)
|
||||
itemClickListener.get().onImageClick(image);
|
||||
}
|
||||
});
|
||||
imageView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (itemClickListener.get() != null)
|
||||
return itemClickListener.get().onImageTouch(image);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Bitmap downscale(Bitmap image) {
|
||||
float ratio = image.getHeight() / 256.0f;
|
||||
int destWidth = (int) (image.getWidth() / ratio);
|
||||
Bitmap result = Bitmap.createScaledBitmap(image, destWidth, 256, false);
|
||||
|
||||
vh.item.setImageBitmap(result);
|
||||
vh.item.setBackgroundColor(0xffffffff);
|
||||
vh.item.setPadding(1, 1, 1, 1);
|
||||
vh.item.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (itemClickListener.get() != null)
|
||||
itemClickListener.get().onImageClick(image);
|
||||
}
|
||||
});
|
||||
vh.item.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (itemClickListener.get() != null)
|
||||
return itemClickListener.get().onImageTouch(image);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return Bitmap.createScaledBitmap(image, destWidth, 256, false);
|
||||
}
|
||||
|
||||
|
||||
class ImageHolder extends ViewHolder {
|
||||
final ImageView item;
|
||||
final View view;
|
||||
|
||||
ImageHolder(ImageView item) {
|
||||
super(item);
|
||||
this.item = item;
|
||||
ImageHolder(View view) {
|
||||
super(view);
|
||||
this.view = view;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,9 +30,10 @@ import java.util.List;
|
|||
public class MessageAdapter extends Adapter<MessageAdapter.MessageHolder> {
|
||||
|
||||
private WeakReference<OnItemSelected> itemClickListener;
|
||||
|
||||
private List<Message> messages;
|
||||
private int highlight;
|
||||
private int fontColor;
|
||||
|
||||
private int highlight, fontColor;
|
||||
private boolean loadImage;
|
||||
|
||||
|
||||
|
@ -44,29 +45,24 @@ public class MessageAdapter extends Adapter<MessageAdapter.MessageHolder> {
|
|||
}
|
||||
|
||||
|
||||
public Message getData(int index) {
|
||||
return messages.get(index);
|
||||
}
|
||||
|
||||
|
||||
public void setData(@NonNull List<Message> messageList) {
|
||||
public void replaceAll(@NonNull List<Message> messageList) {
|
||||
messages.clear();
|
||||
messages.addAll(messageList);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
public void toggleImage(boolean loadImage) {
|
||||
this.loadImage = loadImage;
|
||||
}
|
||||
|
||||
|
||||
public void setColor(int fontColor, int highlight) {
|
||||
this.fontColor = fontColor;
|
||||
this.highlight = highlight;
|
||||
}
|
||||
|
||||
|
||||
public void setImage(boolean loadImage) {
|
||||
this.loadImage = loadImage;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getItemId(int index) {
|
||||
return messages.get(index).getId();
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.List;
|
|||
|
||||
public class TrendAdapter extends Adapter<TrendAdapter.ItemHolder> {
|
||||
|
||||
|
||||
private WeakReference<OnItemClickListener> itemClickListener;
|
||||
private List<Trend> trends;
|
||||
private int font_color;
|
||||
|
|
|
@ -29,9 +29,8 @@ import java.util.List;
|
|||
public class TweetAdapter extends Adapter<TweetAdapter.ItemHolder> {
|
||||
|
||||
private WeakReference<OnItemClickListener> itemClickListener;
|
||||
private List<Tweet> tweets;
|
||||
|
||||
private NumberFormat formatter;
|
||||
private List<Tweet> tweets;
|
||||
private int highlight;
|
||||
private int font_color;
|
||||
private boolean image_load;
|
||||
|
@ -53,20 +52,20 @@ public class TweetAdapter extends Adapter<TweetAdapter.ItemHolder> {
|
|||
}
|
||||
|
||||
|
||||
public void toggleImage(boolean image_load) {
|
||||
public void setImage(boolean image_load) {
|
||||
this.image_load = image_load;
|
||||
}
|
||||
|
||||
|
||||
public Tweet getData(int index) {
|
||||
public Tweet get(int index) {
|
||||
return tweets.get(index);
|
||||
}
|
||||
|
||||
|
||||
public void setData(@NonNull List<Tweet> newTweets) {
|
||||
public void addFirst(@NonNull List<Tweet> newTweets) {
|
||||
if (!newTweets.isEmpty()) {
|
||||
tweets.addAll(0, newTweets);
|
||||
notifyItemInserted(0);
|
||||
notifyItemRangeInserted(0, newTweets.size());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +81,7 @@ public class TweetAdapter extends Adapter<TweetAdapter.ItemHolder> {
|
|||
}
|
||||
|
||||
|
||||
public void removeItem(long id) {
|
||||
public void remove(long id) {
|
||||
int index = -1;
|
||||
for (int pos = 0; pos < tweets.size() && index < 0; pos++) {
|
||||
if (tweets.get(pos).getId() == id) {
|
||||
|
|
|
@ -43,20 +43,20 @@ public class UserAdapter extends Adapter<UserAdapter.ItemHolder> {
|
|||
}
|
||||
|
||||
|
||||
public void setData(@NonNull List<TwitterUser> userList) {
|
||||
public void replaceAll(@NonNull List<TwitterUser> userList) {
|
||||
users.clear();
|
||||
users.addAll(userList);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
public void toggleImage(boolean image) {
|
||||
loadImage = image;
|
||||
public void setColor(int font_color) {
|
||||
this.font_color = font_color;
|
||||
}
|
||||
|
||||
|
||||
public void setColor(int font_color) {
|
||||
this.font_color = font_color;
|
||||
public void setImage(boolean image) {
|
||||
loadImage = image;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.widget.ProgressBar;
|
|||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
|
@ -20,7 +19,7 @@ import java.lang.ref.WeakReference;
|
|||
import java.net.URL;
|
||||
|
||||
|
||||
public class ImageLoader extends AsyncTask<String, Void, Bitmap[]> {
|
||||
public class ImageLoader extends AsyncTask<String, Bitmap, Boolean> {
|
||||
|
||||
public enum Mode {
|
||||
ONLINE,
|
||||
|
@ -41,40 +40,51 @@ public class ImageLoader extends AsyncTask<String, Void, Bitmap[]> {
|
|||
|
||||
|
||||
@Override
|
||||
protected Bitmap[] doInBackground(String[] links) {
|
||||
protected Boolean doInBackground(String[] links) {
|
||||
try {
|
||||
int i = 0;
|
||||
Bitmap[] images = new Bitmap[links.length];
|
||||
for (String link : links) {
|
||||
switch (mode) {
|
||||
case ONLINE:
|
||||
switch (mode) {
|
||||
case ONLINE:
|
||||
for (String link : links) {
|
||||
URL url = new URL(link);
|
||||
InputStream stream = url.openStream();
|
||||
images[i++] = BitmapFactory.decodeStream(stream);
|
||||
break;
|
||||
Bitmap image = BitmapFactory.decodeStream(stream);
|
||||
publishProgress(image);
|
||||
}
|
||||
break;
|
||||
|
||||
case STORAGE:
|
||||
images[i++] = BitmapFactory.decodeFile(link);
|
||||
break;
|
||||
}
|
||||
case STORAGE:
|
||||
for (String link : links) {
|
||||
Bitmap image = BitmapFactory.decodeFile(link);
|
||||
publishProgress(image);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return images;
|
||||
} catch (Exception err) {
|
||||
err.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(@Nullable Bitmap[] images) {
|
||||
protected void onProgressUpdate(Bitmap[] btm) {
|
||||
if (ui.get() != null) {
|
||||
ProgressBar progress = ui.get().findViewById(R.id.image_load);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
if (images != null && images.length > 0) {
|
||||
ui.get().setImage(images[0]);
|
||||
imageAdapter.setImages(images);
|
||||
imageAdapter.notifyDataSetChanged();
|
||||
if (imageAdapter.getItemCount() == 1) {
|
||||
ProgressBar progress = ui.get().findViewById(R.id.image_load);
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
ui.get().setImage(imageAdapter.top());
|
||||
}
|
||||
imageAdapter.addLast(btm[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean success) {
|
||||
if (ui.get() != null) {
|
||||
if (success) {
|
||||
imageAdapter.disableLoading();
|
||||
} else {
|
||||
Toast.makeText(ui.get(), R.string.connection_failed, Toast.LENGTH_SHORT).show();
|
||||
ui.get().finish();
|
||||
|
|
|
@ -53,7 +53,7 @@ public class MessageListFragment extends Fragment implements OnRefreshListener,
|
|||
GlobalSettings settings = GlobalSettings.getInstance(getContext());
|
||||
reload.setProgressBackgroundColorSchemeColor(settings.getHighlightColor());
|
||||
adapter.setColor(settings.getFontColor(), settings.getHighlightColor());
|
||||
adapter.toggleImage(settings.getImageLoad());
|
||||
adapter.setImage(settings.getImageLoad());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ public class TweetListFragment extends Fragment implements OnRefreshListener, On
|
|||
@Override
|
||||
public void onActivityResult(int reqCode, int returnCode, Intent i) {
|
||||
if (reqCode == REQUEST_TWEET_CHANGED && returnCode == RETURN_TWEET_CHANGED)
|
||||
adapter.removeItem(tweetId);
|
||||
adapter.remove(tweetId);
|
||||
super.onActivityResult(reqCode, returnCode, i);
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ public class TweetListFragment extends Fragment implements OnRefreshListener, On
|
|||
@Override
|
||||
public void onItemClick(int pos) {
|
||||
if (reload != null && !reload.isRefreshing()) {
|
||||
Tweet tweet = adapter.getData(pos);
|
||||
Tweet tweet = adapter.get(pos);
|
||||
tweetId = tweet.getId(); // Mark tweet
|
||||
if (tweet.getEmbeddedTweet() != null)
|
||||
tweet = tweet.getEmbeddedTweet();
|
||||
|
@ -215,6 +215,6 @@ public class TweetListFragment extends Fragment implements OnRefreshListener, On
|
|||
if (reload != null)
|
||||
reload.setProgressBackgroundColorSchemeColor(settings.getHighlightColor());
|
||||
adapter.setColor(settings.getHighlightColor(), settings.getFontColor());
|
||||
adapter.toggleImage(settings.getImageLoad());
|
||||
adapter.setImage(settings.getImageLoad());
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@ public class UserListFragment extends Fragment implements OnRefreshListener, OnI
|
|||
reload.setOnRefreshListener(this);
|
||||
adapter = new UserAdapter(this);
|
||||
adapter.setColor(settings.getFontColor());
|
||||
adapter.toggleImage(settings.getImageLoad());
|
||||
adapter.setImage(settings.getImageLoad());
|
||||
list.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
list.setHasFixedSize(fixLayout);
|
||||
list.setAdapter(adapter);
|
||||
|
|
|
@ -103,7 +103,7 @@ public class MessageLoader extends AsyncTask<Long, Void, List<Message>> {
|
|||
protected void onPostExecute(@Nullable List<Message> messages) {
|
||||
if (ui.get() != null) {
|
||||
if (messages != null)
|
||||
adapter.setData(messages);
|
||||
adapter.replaceAll(messages);
|
||||
if (err != null)
|
||||
ErrorHandler.printError(ui.get().getContext(), err);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
|
@ -125,7 +125,7 @@ public class MessageLoader extends AsyncTask<Long, Void, List<Message>> {
|
|||
protected void onCancelled(@Nullable List<Message> messages) {
|
||||
if (ui.get() != null) {
|
||||
if (messages != null)
|
||||
adapter.setData(messages);
|
||||
adapter.replaceAll(messages);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
reload.setRefreshing(false);
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ public class TweetLoader extends AsyncTask<Object, Void, List<Tweet>> {
|
|||
protected void onPostExecute(@Nullable List<Tweet> tweets) {
|
||||
if (ui.get() != null) {
|
||||
if (tweets != null)
|
||||
adapter.setData(tweets);
|
||||
adapter.addFirst(tweets);
|
||||
if (err != null)
|
||||
ErrorHandler.printError(ui.get().getContext(), err);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
|
@ -196,7 +196,7 @@ public class TweetLoader extends AsyncTask<Object, Void, List<Tweet>> {
|
|||
protected void onCancelled(@Nullable List<Tweet> tweets) {
|
||||
if (ui.get() != null) {
|
||||
if (tweets != null)
|
||||
adapter.setData(tweets);
|
||||
adapter.addFirst(tweets);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
reload.setRefreshing(false);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public class UserLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
|
|||
protected void onPostExecute(@Nullable List<TwitterUser> users) {
|
||||
if (ui.get() != null) {
|
||||
if (users != null)
|
||||
adapter.setData(users);
|
||||
adapter.replaceAll(users);
|
||||
else if (err != null)
|
||||
ErrorHandler.printError(ui.get().getContext(), err);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
|
@ -121,7 +121,7 @@ public class UserLoader extends AsyncTask<Object, Void, List<TwitterUser>> {
|
|||
protected void onCancelled(@Nullable List<TwitterUser> users) {
|
||||
if (ui.get() != null) {
|
||||
if (users != null)
|
||||
adapter.setData(users);
|
||||
adapter.replaceAll(users);
|
||||
SwipeRefreshLayout reload = ui.get().findViewById(R.id.fragment_reload);
|
||||
reload.setRefreshing(false);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue