해당 강좌는 링크에서 볼 수 있습니다.
명시되지 않은 모든 소스코드 출처 : www.androidhive.info
FeedImageView.java
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 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | public class FeedImageView extends ImageView { public interface ResponseObserver { public void onError(); public void onSuccess(); } private ResponseObserver mObserver; public void setResponseObserver(ResponseObserver observer) { mObserver = observer; } /** * The URL of the network image to load */ private String mUrl; /** * Resource ID of the image to be used as a placeholder until the network * image is loaded. */ private int mDefaultImageId; /** * Resource ID of the image to be used if the network response fails. */ private int mErrorImageId; /** * Local copy of the ImageLoader. */ private ImageLoader mImageLoader; /** * Current ImageContainer. (either in-flight or finished) */ private ImageContainer mImageContainer; public FeedImageView(Context context) { this(context, null); } public FeedImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FeedImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } /** * Sets URL of the image that should be loaded into this view. Note that * calling this will immediately either set the cached image (if available) * or the default image specified by * {@link VolleyImageView#setDefaultImageResId(int)} on the view. * * NOTE: If applicable, {@link VolleyImageView#setDefaultImageResId(int)} * and {@link VolleyImageView#setErrorImageResId(int)} should be called * prior to calling this function. * * @param url * The URL that should be loaded into this ImageView. * @param imageLoader * ImageLoader that will be used to make the request. */ public void setImageUrl(String url, ImageLoader imageLoader) { mUrl = url; mImageLoader = imageLoader; // The URL has potentially changed. See if we need to load it. loadImageIfNecessary(false); } /** * Sets the default image resource ID to be used for this view until the * attempt to load it completes. */ public void setDefaultImageResId(int defaultImage) { mDefaultImageId = defaultImage; } /** * Sets the error image resource ID to be used for this view in the event * that the image requested fails to load. */ public void setErrorImageResId(int errorImage) { mErrorImageId = errorImage; } /** * Loads the image for the view if it isn't already loaded. * * @param isInLayoutPass * True if this was invoked from a layout pass, false otherwise. */ private void loadImageIfNecessary(final boolean isInLayoutPass) { final int width = getWidth(); int height = getHeight(); boolean isFullyWrapContent = getLayoutParams() != null && getLayoutParams().height == LayoutParams.WRAP_CONTENT && getLayoutParams().width == LayoutParams.WRAP_CONTENT; // if the view's bounds aren't known yet, and this is not a // wrap-content/wrap-content // view, hold off on loading the image. if (width == 0 && height == 0 && !isFullyWrapContent) { return; } // if the URL to be loaded in this view is empty, cancel any old // requests and clear the // currently loaded image. if (TextUtils.isEmpty(mUrl)) { if (mImageContainer != null) { mImageContainer.cancelRequest(); mImageContainer = null; } setDefaultImageOrNull(); return; } // if there was an old request in this view, check if it needs to be // canceled. if (mImageContainer != null && mImageContainer.getRequestUrl() != null) { if (mImageContainer.getRequestUrl().equals(mUrl)) { // if the request is from the same URL, return. return; } else { // if there is a pre-existing request, cancel it if it's // fetching a different URL. mImageContainer.cancelRequest(); setDefaultImageOrNull(); } } // The pre-existing content of this view didn't match the current URL. // Load the new image // from the network. ImageContainer newContainer = mImageLoader.get(mUrl, new ImageListener() { @Override public void onErrorResponse(VolleyError error) { if (mErrorImageId != 0) { setImageResource(mErrorImageId); } if (mObserver != null) { mObserver.onError(); } } @Override public void onResponse(final ImageContainer response, boolean isImmediate) { // If this was an immediate response that was delivered // inside of a layout // pass do not set the image immediately as it will // trigger a requestLayout // inside of a layout. Instead, defer setting the image // by posting back to // the main thread. if (isImmediate && isInLayoutPass) { post(new Runnable() { @Override public void run() { onResponse(response, false); } }); return; } int bWidth = 0, bHeight = 0; if (response.getBitmap() != null) { setImageBitmap(response.getBitmap()); bWidth = response.getBitmap().getWidth(); bHeight = response.getBitmap().getHeight(); adjustImageAspect(bWidth, bHeight); } else if (mDefaultImageId != 0) { setImageResource(mDefaultImageId); } if (mObserver != null) { mObserver.onSuccess(); } } }); // update the ImageContainer to be the new bitmap container. mImageContainer = newContainer; } private void setDefaultImageOrNull() { if (mDefaultImageId != 0) { setImageResource(mDefaultImageId); } else { setImageBitmap(null); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); loadImageIfNecessary(true); } @Override protected void onDetachedFromWindow() { if (mImageContainer != null) { // If the view was bound to an image request, cancel it and clear // out the image from the view. mImageContainer.cancelRequest(); setImageBitmap(null); // also clear out the container so we can reload the image if // necessary. mImageContainer = null; } super.onDetachedFromWindow(); } @Override protected void drawableStateChanged() { super.drawableStateChanged(); invalidate(); } /* * Adjusting imageview height * */ private void adjustImageAspect(int bWidth, int bHeight) { LinearLayout.LayoutParams params = (LayoutParams) getLayoutParams(); if (bWidth == 0 || bHeight == 0) return; int swidth = getWidth(); int new_height = 0; new_height = swidth * bHeight / bWidth; params.width = swidth; params.height = new_height; setLayoutParams(params); } } | cs |
feed_item.xml
이것을 추가하기 전에 반드시 다음을 먼저 추가합니다.
1 2 3 4 5 6 7 8 9 10 11 | res -> values / colors <?xml version="1.0" encoding="utf-8"?> <resources> <color name="white">#ffffff</color> <color name="feed_bg">#d3d6db</color> <color name="feed_item_bg">#ffffff</color> <color name="feed_item_border">#c2c3c8</color> <color name="link">#0a80d1</color> <color name="timestamp">#a0a3a7</color> </resources> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | res => drawable / bg_parent_rounded_corner.xml (add this) <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <!-- view background color --> <solid android:color="@color/feed_item_bg" > </solid> <!-- view border color and width --> <stroke android:width="@dimen/feed_item_border_width" android:color="@color/feed_item_border" > </stroke> <!-- Here is the corner radius --> <corners android:radius="@dimen/feed_item_corner_radius" > </corners> </shape> | cs |
이후에 feed_item.xml을 추가합니다.
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 | feed_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/feed_bg" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="@dimen/feed_item_margin" android:layout_marginRight="@dimen/feed_item_margin" android:layout_marginTop="@dimen/feed_item_margin" android:background="@drawable/bg_parent_rounded_corner" android:orientation="vertical" android:paddingBottom="@dimen/feed_item_padding_top_bottom" android:paddingTop="@dimen/feed_item_padding_top_bottom" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingLeft="@dimen/feed_item_padding_left_right" android:paddingRight="@dimen/feed_item_padding_left_right" > <com.android.volley.toolbox.NetworkImageView android:id="@+id/profilePic" android:layout_width="@dimen/feed_item_profile_pic" android:layout_height="@dimen/feed_item_profile_pic" android:scaleType="fitCenter" > </com.android.volley.toolbox.NetworkImageView> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:paddingLeft="@dimen/feed_item_profile_info_padd" > <TextView android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="@dimen/feed_item_profile_name" android:textStyle="bold" /> <TextView android:id="@+id/timestamp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@color/timestamp" android:textSize="@dimen/feed_item_timestamp" /> </LinearLayout> </LinearLayout> <TextView android:id="@+id/txtStatusMsg" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="5dp" android:paddingLeft="@dimen/feed_item_status_pad_left_right" android:paddingRight="@dimen/feed_item_status_pad_left_right" android:paddingTop="@dimen/feed_item_status_pad_top" /> <TextView android:id="@+id/txtUrl" android:layout_width="fill_parent" android:layout_height="wrap_content" android:linksClickable="true" android:paddingBottom="10dp" android:paddingLeft="@dimen/feed_item_status_pad_left_right" android:paddingRight="@dimen/feed_item_status_pad_left_right" android:textColorLink="@color/link" /> <info.androidhive.listviewfeed.FeedImageView android:id="@+id/feedImage1" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:scaleType="fitXY" android:visibility="visible" /> </LinearLayout> </LinearLayout> | cs |
'안드로이드 > 코드' 카테고리의 다른 글
[#B7 DEPRECATED] TouchImageView.java (0) | 2018.12.07 |
---|---|
[#B5 DEPRECATED]JSON 오브젝트를 String으로 변환하는 방법 - JsonUtil (0) | 2018.11.30 |
[#B4 DEPRECATED]STRING을 BITMAP으로 변환하기 (0) | 2018.11.28 |
[#B3 DEPRECATED]BITMAP을 STRING으로 변환하기 (0) | 2018.11.28 |
[#B2 DEPRECATED]RoundImageView.java (0) | 2018.11.28 |