java - 当手机没有任何互联网时无法从 url 获取图标,或者是否可以保存在内部存储然后从那里读取

标签 java android android-fragments xml-parsing

  1. 我有一个已解析的 XML,我从那里读取了数据。我已经手动声明了一些数据,其他数据将由用户保存。
  2. 我已使用 glide 声明,但它没有获得正确的图标,或者当没有互联网时图标被隐藏。
  3. 声明的 xml 它们在可绘制对象中具有图标,当我解析它们时它们是可读的并且我可以显示。

我想要的是有任何选项可以获取网站图标并保存到可绘制对象或内部存储或缓存中,这样即使我没有互联网也可以阅读。 手动声明并为它们解析的项目从 drawable 中获取图标,但对于其他项目,从 url 中获取图标。

这是我到目前为止尝试过的方法。

Pojo.class

public class Bookmark implements Parcelable, Comparable  {
    String name, id, nativeUrl, searchUrl;
    long db_id;
    int icon;
    int viewType;

    // Constructor, getters, setters & other default functions are omitted for simplicity.
}

Adapter.class

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    ArrayList<Bookmark> arrayList;
    BookmarkDB bookmarkDB;
    public static final int ITEM_TYPE_ONE = 0;
    public static final int ITEM_TYPE_TWO = 1;
    boolean connected = false;
    String BASE_URL = "https://besticon-demo.herokuapp.com/icon?url=";
    public MyAdapter(Context context, ArrayList<Bookmark> arrayList) {
        this.context = context;
        this.arrayList = arrayList;
    }

    private boolean switchOnOff;

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        View view = null;
        if (viewType == ITEM_TYPE_ONE) {
            view = LayoutInflater.from(context).inflate(R.layout.grid_item, parent, false);
            return new ViewHolder(view);
        } else if (viewType == ITEM_TYPE_TWO) {
            view = LayoutInflater.from(context).inflate(R.layout.add_bookmark, parent, false);
            return new ButtonViewHolder(view);
        } else {
            return  null;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        final int itemType = getItemViewType(position);
        if (itemType == ITEM_TYPE_ONE) {
            final ViewHolder viewHolder = (ViewHolder) holder;
            viewHolder.tvName.setText(arrayList.get(position).getName());
            RequestOptions requestOptions = new RequestOptions();
            bookmarkDB = new BookmarkDB(context);
                viewHolder.tvIcon.setImageResource(arrayList.get(position).getIcon());         

            Glide.with(context)
                    .load(BASE_URL+arrayList.get(position).getSearchUrl() + "&size=32;")
                    .apply(requestOptions)
                    .into(viewHolder.tvIcon);

            viewHolder.tvIcon.setImageResource(arrayList.get(position).getIcon());
            viewHolder.tvId.setText(arrayList.get(position).getId());
            viewHolder.tvSearchUrl.setText(arrayList.get(position).getSearchUrl()); 
        } else if (itemType == ITEM_TYPE_TWO) {
            ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder;
            buttonViewHolder.imgButton.setImageResource(arrayList.get(position).getIcon());
        }
    }

    @Override
    public int getItemViewType(int position) {
        // Based on you list you will return the ViewType 
        if (arrayList.get(position).getViewType() == 0) return ITEM_TYPE_ONE;
        else return ITEM_TYPE_TWO;
    }
}

Ass 你可以在 Adapter.class 中看到

// This get the icon from drawable and it sets to parsed array.
viewHolder.tvIcon.setImageResource(arrayList.get(position).getIcon());

// This gets the icon from URL and sets it to the parsed array but only when the user has internet.
Glide.with(context)
    .load(BASE_URL+arrayList.get(position).getSearchUrl() + &size=32;")
    .apply(requestOptions)
    .into(viewHolder.tvIcon);

这是我解析过的声明的XML,它在res/xml/bookmarks.xml下声明的文件

<Bookmarks>
    <Bookmark name="Bing" hidden="" icon="bing" id="0" nativeUrl="" searchUrl="https://www.bing.com" />
    <Bookmark name="Google"  hidden="" icon="google" id="1" nativeUrl="" searchUrl="https://www.google.com" />
    <Bookmark name="Youtube" hidden="" icon="youtube" id="2" nativeUrl="" searchUrl="http://m.youtube.com" />
</Bookmarks>

最佳答案

所以如果我理解正确的话,你有两个问题。

  1. 当没有互联网时,默认图标不显示(即隐藏)。
  2. 即使没有互联网,您也希望在加载后显示图像。

这两个都可以使用 Glide 来实现,只需对代码进行最小的更改。只需像下面这样使用 Glide 更改代码的图像加载部分。

String imageUrl = BASE_URL + arrayList.get(position).getSearchUrl() + "&size=32";
Glide.with(context)
    .load(imageUrl)
    .diskCacheStrategy(DiskCacheStrategy.ALL) 
    .placeholder(R.drawable.placeholder)
    .into(viewHolder.tvIcon);

DiskCacheStrategy.ALL 管理图像缓存,即使设备处于离线状态也应加载图像。使用 .placeholder(R.drawable.placeholder) 设置占位符可用于当图像因网络问题而未加载且因此您想显示默认图像时。

如果您想阅读更多有关缓存策略的信息,this link也可以提供帮助。

更新 1

根据您的评论,我认为您应该在此处添加一个if 语句。当 drawable 在本地可用时,您将使用 setImageResource 函数,else 使用 Glide 加载图像。

更新 2

如果您使用带有 DiskStrategy.ALL 的 Glide,则不必在本地保存图像。它将缓存图像并在互联网连接不可用时自动显示。我想建议您删除手动设置。

更新 3

如果你想使用你自己的drawable中的一些图标,那么你可以考虑放这样的东西。

if (theIconIsAvailableInDrawable) showThatFromDrawable();
else useGlideToShowTheIconFromUrlUsingDiskCacheStrategy();

希望你明白了。

关于java - 当手机没有任何互联网时无法从 url 获取图标,或者是否可以保存在内部存储然后从那里读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54536787/

相关文章:

android - 等待操作,直到创建 Fragment 的 View

java - JSF:我的应用程序中未引用 javax.faces.resources

java - Hibernate 嵌套属性别名

android - 为什么我不能使用 Uri 类进行调用?

android - 构建播放器时出错 : Vuforia Engine does not support Android TV

android - Action Bar UP 导航 Activity 到 Fragment

java - 如何使用Spring Security自定义登录页面?

java - 在特定的 JTable 单元格上设置焦点和闪烁光标

java - ImageButtons 不从主题样式获取属性

android - 防止在加载后重新添加 fragment