improved image loading, bug fix

This commit is contained in:
NudeDude 2019-06-23 12:32:39 +02:00
parent d91c892275
commit b412c2e802
12 changed files with 150 additions and 93 deletions

View File

@ -4,63 +4,108 @@ 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];
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() {
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);
}
});
vh.item.setOnLongClickListener(new View.OnLongClickListener() {
imageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (itemClickListener.get() != null)
@ -69,14 +114,22 @@ public class ImageAdapter extends Adapter<ImageAdapter.ImageHolder> {
}
});
}
}
private Bitmap downscale(Bitmap image) {
float ratio = image.getHeight() / 256.0f;
int destWidth = (int) (image.getWidth() / ratio);
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;
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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:
for (String link : links) {
URL url = new URL(link);
InputStream stream = url.openStream();
images[i++] = BitmapFactory.decodeStream(stream);
Bitmap image = BitmapFactory.decodeStream(stream);
publishProgress(image);
}
break;
case STORAGE:
images[i++] = BitmapFactory.decodeFile(link);
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) {
if (imageAdapter.getItemCount() == 1) {
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();
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();

View File

@ -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;
}

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}