admin
2021-07-20 27bd1f81221b8c8e8047118a64c2beb7bc214bbb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*******************************************************************************
 * Copyright 2014 Sergey Tarasevich
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package com.nostra13.universalimageloader.core.imageaware;
 
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Looper;
import android.view.View;
import android.view.ViewGroup;
import com.nostra13.universalimageloader.core.assist.ViewScaleType;
import com.nostra13.universalimageloader.utils.L;
 
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
 
/**
 * Wrapper for Android {@link android.view.View View}. Keeps weak reference of View to prevent memory leaks.
 *
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 * @since 1.9.2
 */
public abstract class ViewAware implements ImageAware {
 
    public static final String WARN_CANT_SET_DRAWABLE = "Can't set a drawable into view. You should call ImageLoader on UI thread for it.";
    public static final String WARN_CANT_SET_BITMAP = "Can't set a bitmap into view. You should call ImageLoader on UI thread for it.";
 
    protected Reference<View> viewRef;
    protected boolean checkActualViewSize;
 
    /**
     * Constructor. <br />
     * References {@link #ViewAware(android.view.View, boolean) ImageViewAware(imageView, true)}.
     *
     * @param view {@link android.view.View View} to work with
     */
    public ViewAware(View view) {
        this(view, true);
    }
 
    /**
     * Constructor
     *
     * @param view                {@link android.view.View View} to work with
     * @param checkActualViewSize <b>true</b> - then {@link #getWidth()} and {@link #getHeight()} will check actual
     *                            size of View. It can cause known issues like
     *                            <a href="https://github.com/nostra13/Android-Universal-Image-Loader/issues/376">this</a>.
     *                            But it helps to save memory because memory cache keeps bitmaps of actual (less in
     *                            general) size.
     *                            <p/>
     *                            <b>false</b> - then {@link #getWidth()} and {@link #getHeight()} will <b>NOT</b>
     *                            consider actual size of View, just layout parameters. <br /> If you set 'false'
     *                            it's recommended 'android:layout_width' and 'android:layout_height' (or
     *                            'android:maxWidth' and 'android:maxHeight') are set with concrete values. It helps to
     *                            save memory.
     */
    public ViewAware(View view, boolean checkActualViewSize) {
        if (view == null) throw new IllegalArgumentException("view must not be null");
 
        this.viewRef = new WeakReference<View>(view);
        this.checkActualViewSize = checkActualViewSize;
    }
 
    /**
     * {@inheritDoc}
     * <p/>
     * Width is defined by target {@link android.view.View view} parameters, configuration
     * parameters or device display dimensions.<br />
     * Size computing algorithm (go by steps until get non-zero value):<br />
     * 1) Get the actual drawn <b>getWidth()</b> of the View<br />
     * 2) Get <b>layout_width</b>
     */
    @Override
    public int getWidth() {
        View view = viewRef.get();
        if (view != null) {
            final ViewGroup.LayoutParams params = view.getLayoutParams();
            int width = 0;
            if (checkActualViewSize && params != null && params.width != ViewGroup.LayoutParams.WRAP_CONTENT) {
                width = view.getWidth(); // Get actual image width
            }
            if (width <= 0 && params != null) width = params.width; // Get layout width parameter
            return width;
        }
        return 0;
    }
 
    /**
     * {@inheritDoc}
     * <p/>
     * Height is defined by target {@link android.view.View view} parameters, configuration
     * parameters or device display dimensions.<br />
     * Size computing algorithm (go by steps until get non-zero value):<br />
     * 1) Get the actual drawn <b>getHeight()</b> of the View<br />
     * 2) Get <b>layout_height</b>
     */
    @Override
    public int getHeight() {
        View view = viewRef.get();
        if (view != null) {
            final ViewGroup.LayoutParams params = view.getLayoutParams();
            int height = 0;
            if (checkActualViewSize && params != null && params.height != ViewGroup.LayoutParams.WRAP_CONTENT) {
                height = view.getHeight(); // Get actual image height
            }
            if (height <= 0 && params != null) height = params.height; // Get layout height parameter
            return height;
        }
        return 0;
    }
 
    @Override
    public ViewScaleType getScaleType() {
        return ViewScaleType.CROP;
    }
 
    @Override
    public View getWrappedView() {
        return viewRef.get();
    }
 
    @Override
    public boolean isCollected() {
        return viewRef.get() == null;
    }
 
    @Override
    public int getId() {
        View view = viewRef.get();
        return view == null ? super.hashCode() : view.hashCode();
    }
 
    @Override
    public boolean setImageDrawable(Drawable drawable) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            View view = viewRef.get();
            if (view != null) {
                setImageDrawableInto(drawable, view);
                return true;
            }
        } else {
            L.w(WARN_CANT_SET_DRAWABLE);
        }
        return false;
    }
 
    @Override
    public boolean setImageBitmap(Bitmap bitmap) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            View view = viewRef.get();
            if (view != null) {
                setImageBitmapInto(bitmap, view);
                return true;
            }
        } else {
            L.w(WARN_CANT_SET_BITMAP);
        }
        return false;
    }
 
    /**
     * Should set drawable into incoming view. Incoming view is guaranteed not null.<br />
     * This method is called on UI thread.
     */
    protected abstract void setImageDrawableInto(Drawable drawable, View view);
 
    /**
     * Should set Bitmap into incoming view. Incoming view is guaranteed not null.< br />
     * This method is called on UI thread.
     */
    protected abstract void setImageBitmapInto(Bitmap bitmap, View view);
}