Android UI-开源框架ImageLoader的完美例子,字节跳动Andorid岗25k+的面试题

  • 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.example.universalimageloader;

import android.app.Activity;

import android.view.Menu;

import android.view.MenuItem;

import com.nostra13.universalimageloader.core.ImageLoader;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

public abstract class BaseActivity extends Activity {

protected ImageLoader imageLoader = ImageLoader.getInstance();

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// 加载菜单

getMenuInflater().inflate(R.menu.main_menu, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.item_clear_memory_cache:

imageLoader.clearMemoryCache(); // 清除内存缓存

return true;

case R.id.item_clear_disc_cache:

imageLoader.clearDiscCache(); // 清除SD卡中的缓存

return true;

default:

return false;

}

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/AbsListViewBaseActivity.java

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.widget.AbsListView;

import com.nostra13.universalimageloader.core.assist.PauseOnScrollListener;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

public class AbsListViewBaseActivity extends BaseActivity {

protected static final String STATE_PAUSE_ON_SCROLL = “STATE_PAUSE_ON_SCROLL”;

protected static final String STATE_PAUSE_ON_FLING = “STATE_PAUSE_ON_FLING”;

protected AbsListView listView;

protected boolean pauseOnScroll = false;

protected boolean pauseOnFling = true;

@Override

public void onRestoreInstanceState(Bundle savedInstanceState) {

pauseOnScroll = savedInstanceState.getBoolean(STATE_PAUSE_ON_SCROLL, false);

pauseOnFling = savedInstanceState.getBoolean(STATE_PAUSE_ON_FLING, true);

}

@Override

public void onResume() {

super.onResume();

applyScrollListener();

}

private void applyScrollListener() {

listView.setOnScrollListener(new PauseOnScrollListener(imageLoader, pauseOnScroll, pauseOnFling));

}

@Override

public void onSaveInstanceState(Bundle outState) {

outState.putBoolean(STATE_PAUSE_ON_SCROLL, pauseOnScroll);

outState.putBoolean(STATE_PAUSE_ON_FLING, pauseOnFling);

}

@Override

public boolean onPrepareOptionsMenu(Menu menu) {

MenuItem pauseOnScrollItem = menu.findItem(R.id.item_pause_on_scroll);

pauseOnScrollItem.setVisible(true);

pauseOnScrollItem.setChecked(pauseOnScroll);

MenuItem pauseOnFlingItem = menu.findItem(R.id.item_pause_on_fling);

pauseOnFlingItem.setVisible(true);

pauseOnFlingItem.setChecked(pauseOnFling);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.item_pause_on_scroll:

pauseOnScroll = !pauseOnScroll;

item.setChecked(pauseOnScroll);

applyScrollListener();

return true;

case R.id.item_pause_on_fling:

pauseOnFling = !pauseOnFling;

item.setChecked(pauseOnFling);

applyScrollListener();

return true;

default:

return super.onOptionsItemSelected(item);

}

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/Constants.java

常量类代码

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

  • 常量类

*/

public final class Constants {

// 一堆图片链接

public static final String[] IMAGES = new String[] {

// Heavy images

“https://lh6.googleusercontent.com/-jZgveEqb6pg/T3R4kXScycI/AAAAAAAAAE0/xQ7CvpfXDzc/s1024/sample_image_01.jpg”,

“https://lh4.googleusercontent.com/-K2FMuOozxU0/T3R4lRAiBTI/AAAAAAAAAE8/a3Eh9JvnnzI/s1024/sample_image_02.jpg”,

“https://lh5.googleusercontent.com/-SCS5C646rxM/T3R4l7QB6xI/AAAAAAAAAFE/xLcuVv3CUyA/s1024/sample_image_03.jpg”,

“https://lh6.googleusercontent.com/-f0NJR6-_Thg/T3R4mNex2wI/AAAAAAAAAFI/45oug4VE8MI/s1024/sample_image_04.jpg”,

“https://lh3.googleusercontent.com/-n-xcJmiI0pg/T3R4mkSchHI/AAAAAAAAAFU/EoiNNb7kk3A/s1024/sample_image_05.jpg”,

“https://lh3.googleusercontent.com/-X43vAudm7f4/T3R4nGSChJI/AAAAAAAAAFk/3bna6D-2EE8/s1024/sample_image_06.jpg”,

“https://lh5.googleusercontent.com/-MpZneqIyjXU/T3R4nuGO1aI/AAAAAAAAAFg/r09OPjLx1ZY/s1024/sample_image_07.jpg”,

“https://lh6.googleusercontent.com/-ql3YNfdClJo/T3XvW9apmFI/AAAAAAAAAL4/_6HFDzbahc4/s1024/sample_image_08.jpg”,

“https://lh5.googleusercontent.com/-Pxa7eqF4cyc/T3R4oasvPEI/AAAAAAAAAF0/-uYDH92h8LA/s1024/sample_image_09.jpg”,

“https://lh4.googleusercontent.com/-Li-rjhFEuaI/T3R4o-VUl4I/AAAAAAAAAF8/5E5XdMnP1oE/s1024/sample_image_10.jpg”,

“https://lh5.googleusercontent.com/-_HU4fImgFhA/T3R4pPVIwWI/AAAAAAAAAGA/0RfK_Vkgth4/s1024/sample_image_11.jpg”,

“https://lh6.googleusercontent.com/-0gnNrVjwa0Y/T3R4peGYJwI/AAAAAAAAAGU/uX_9wvRPM9I/s1024/sample_image_12.jpg”,

“https://lh3.googleusercontent.com/-HBxuzALS_Zs/T3R4qERykaI/AAAAAAAAAGQ/_qQ16FaZ1q0/s1024/sample_image_13.jpg”,

“https://lh4.googleusercontent.com/-cKojDrARNjQ/T3R4qfWSGPI/AAAAAAAAAGY/MR5dnbNaPyY/s1024/sample_image_14.jpg”,

“https://lh3.googleusercontent.com/-WujkdYfcyZ8/T3R4qrIMGUI/AAAAAAAAAGk/277LIdgvnjg/s1024/sample_image_15.jpg”,

“https://lh6.googleusercontent.com/-FMHR7Vy3PgI/T3R4rOXlEKI/AAAAAAAAAGs/VeXrDNDBkaw/s1024/sample_image_16.jpg”,

“https://lh4.googleusercontent.com/-mrR0AJyNTH0/T3R4rZs6CuI/AAAAAAAAAG0/UE1wQqCOqLA/s1024/sample_image_17.jpg”,

“https://lh6.googleusercontent.com/-z77w0eh3cow/T3R4rnLn05I/AAAAAAAAAG4/BaerfWoNucU/s1024/sample_image_18.jpg”,

“https://lh5.googleusercontent.com/-aWVwh1OU5Bk/T3R4sAWw0yI/AAAAAAAAAHE/4_KAvJttFwA/s1024/sample_image_19.jpg”,

“https://lh6.googleusercontent.com/-q-js52DMnWQ/T3R4tZhY2sI/AAAAAAAAAHM/A8kjp2Ivdqg/s1024/sample_image_20.jpg”,

“https://lh5.googleusercontent.com/-_jIzvvzXKn4/T3R4t7xpdVI/AAAAAAAAAHU/7QC6eZ10jgs/s1024/sample_image_21.jpg”,

“https://lh3.googleusercontent.com/-lnGi4IMLpwU/T3R4uCMa7vI/AAAAAAAAAHc/1zgzzz6qTpk/s1024/sample_image_22.jpg”,

“https://lh5.googleusercontent.com/-fFCzKjFPsPc/T3R4u0SZPFI/AAAAAAAAAHk/sbgjzrktOK0/s1024/sample_image_23.jpg”,

“https://lh4.googleusercontent.com/-8TqoW5gBE_Y/T3R4vBS3NPI/AAAAAAAAAHs/EZYvpNsaNXk/s1024/sample_image_24.jpg”,

“https://lh6.googleusercontent.com/-gc4eQ3ySdzs/T3R4vafoA7I/AAAAAAAAAH4/yKii5P6tqDE/s1024/sample_image_25.jpg”,

“https://lh5.googleusercontent.com/–NYOPCylU7Q/T3R4vjAiWkI/AAAAAAAAAH8/IPNx5q3ptRA/s1024/sample_image_26.jpg”,

“https://lh6.googleusercontent.com/-9IJM8so4vCI/T3R4vwJO2yI/AAAAAAAAAIE/ljlr-cwuqZM/s1024/sample_image_27.jpg”,

“https://lh4.googleusercontent.com/-KW6QwOHfhBs/T3R4w0RsQiI/AAAAAAAAAIM/uEFLVgHPFCk/s1024/sample_image_28.jpg”,

“https://lh4.googleusercontent.com/-z2557Ec1ctY/T3R4x3QA2hI/AAAAAAAAAIk/9-GzPL1lTWE/s1024/sample_image_29.jpg”,

“https://lh5.googleusercontent.com/-LaKXAn4Kr1c/T3R4yc5b4lI/AAAAAAAAAIY/fMgcOVQfmD0/s1024/sample_image_30.jpg”,

“https://lh4.googleusercontent.com/-F9LRToJoQdo/T3R4yrLtyQI/AAAAAAAAAIg/ri9uUCWuRmo/s1024/sample_image_31.jpg”,

“https://lh4.googleusercontent.com/-6X-xBwP-QpI/T3R4zGVboII/AAAAAAAAAIs/zYH4PjjngY0/s1024/sample_image_32.jpg”,

“https://lh5.googleusercontent.com/-VdLRjbW4LAs/T3R4zXu3gUI/AAAAAAAAAIw/9aFp9t7mCPg/s1024/sample_image_33.jpg”,

“https://lh6.googleusercontent.com/-gL6R17_fDJU/T3R4zpIXGjI/AAAAAAAAAI8/Q2Vjx-L9X20/s1024/sample_image_34.jpg”,

“https://lh3.googleusercontent.com/-1fGH4YJXEzo/T3R40Y1B7KI/AAAAAAAAAJE/MnTsa77g-nk/s1024/sample_image_35.jpg”,

“https://lh4.googleusercontent.com/-Ql0jHSrea-A/T3R403mUfFI/AAAAAAAAAJM/qzI4SkcH9tY/s1024/sample_image_36.jpg”,

“https://lh5.googleusercontent.com/-BL5FIBR_tzI/T3R41DA0AKI/AAAAAAAAAJk/GZfeeb-SLM0/s1024/sample_image_37.jpg”,

“https://lh4.googleusercontent.com/-wF2Vc9YDutw/T3R41fR2BCI/AAAAAAAAAJc/JdU1sHdMRAk/s1024/sample_image_38.jpg”,

“https://lh6.googleusercontent.com/-ZWHiPehwjTI/T3R41zuaKCI/AAAAAAAAAJg/hR3QJ1v3REg/s1024/sample_image_39.jpg”,

// Light images

“http://tabletpcssource.com/wp-content/uploads/2011/05/android-logo.png”,

“http://simpozia.com/pages/images/stories/windows-icon.png”,

“https://si0.twimg.com/profile_images/1135218951/gmail_profile_icon3_normal.png”,

“http://www.krify.net/wp-content/uploads/2011/09/Macromedia_Flash_dock_icon.png”,

“http://radiotray.sourceforge.net/radio.png”,

“http://www.bandwidthblog.com/wp-content/uploads/2011/11/twitter-logo.png”,

“http://weloveicons.s3.amazonaws.com/icons/100907_itunes1.png”,

“http://weloveicons.s3.amazonaws.com/icons/100929_applications.png”,

“http://www.idyllicmusic.com/index_files/get_apple-iphone.png”,

“http://www.frenchrevolutionfood.com/wp-content/uploads/2009/04/Twitter-Bird.png”,

“http://3.bp.blogspot.com/-ka5MiRGJ_S4/TdD9OoF6bmI/AAAAAAAAE8k/7ydKtptUtSg/s1600/Google_Sky%2BMaps_Android.png”,

“http://www.desiredsoft.com/images/icon_webhosting.png”,

“http://goodereader.com/apps/wp-content/uploads/downloads/thumbnails/2012/01/hi-256-0-99dda8c730196ab93c67f0659d5b8489abdeb977.png”,

“http://1.bp.blogspot.com/-mlaJ4p_3rBU/TdD9OWxN8II/AAAAAAAAE8U/xyynWwr3_4Q/s1600/antivitus_free.png”,

“http://cdn3.iconfinder.com/data/icons/transformers/computer.png”,

“http://cdn.geekwire.com/wp-content/uploads/2011/04/firefox.png?7794fe”,

“https://ssl.gstatic.com/android/market/com.rovio.angrybirdsseasons/hi-256-9-347dae230614238a639d21508ae492302340b2ba”,

“http://androidblaze.com/wp-content/uploads/2011/12/tablet-pc-256x256.jpg”,

“http://www.theblaze.com/wp-content/uploads/2011/08/Apple.png”,

“http://1.bp.blogspot.com/-y-HQwQ4Kuu0/TdD9_iKIY7I/AAAAAAAAE88/3G4xiclDZD0/s1600/Twitter_Android.png”,

“http://3.bp.blogspot.com/-nAf4IMJGpc8/TdD9OGNUHHI/AAAAAAAAE8E/VM9yU_lIgZ4/s1600/Adobe%2BReader_Android.png”,

“http://cdn.geekwire.com/wp-content/uploads/2011/05/oovoo-android.png?7794fe”,

“http://icons.iconarchive.com/icons/kocco/ndroid/128/android-market-2-icon.png”,

“http://thecustomizewindows.com/wp-content/uploads/2011/11/Nicest-Android-Live-Wallpapers.png”,

“http://c.wrzuta.pl/wm16596/a32f1a47002ab3a949afeb4f”,

“http://macprovid.vo.llnwd.net/o43/hub/media/1090/6882/01_headline_Muse.jpg”,

// Special cases

“http://cdn.urbanislandz.com/wp-content/uploads/2011/10/MMSposter-large.jpg”, // very large image

“file:///sdcard/Universal Image Loader @#&=±_.,!()~'%20.png”, // Image from SD card with encoded symbols

“assets://Living Things @#&=±_.,!()~'%20.jpg”, // Image from assets

“drawable://” + R.drawable.ic_launcher, // Image from drawables

“http://upload.wikimedia.org/wikipedia/ru/b/b6/袣邪泻_泻芯褌_褋_屑褘褕邪屑懈_胁芯械胁邪谢.png”, // Link with UTF-8

“https://www.eff.org/sites/default/files/chrome150_0.jpg”, // Image from HTTPS

“http://bit.ly/soBiXr”, // Redirect link

“http://img001.us.expono.com/100001/100001-1bc30-2d736f_m.jpg”, // EXIF

“”, // Empty link

“http://wrong.site.com/corruptedLink”, // Wrong link

};

private Constants() {

}

// 配置

public static class Config {

public static final boolean DEVELOPER_MODE = false;

}

// 额外类

public static class Extra {

public static final String IMAGES = “com.nostra13.example.universalimageloader.IMAGES”;

public static final String IMAGE_POSITION = “com.nostra13.example.universalimageloader.IMAGE_POSITION”;

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageListActivity.java

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

import java.util.Collections;

import java.util.LinkedList;

import java.util.List;

import android.content.Intent;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

import com.nostra13.example.universalimageloader.Constants.Extra;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;

import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;

import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;

/**

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

public class ImageListActivity extends AbsListViewBaseActivity {

DisplayImageOptions options; // DisplayImageOptions是用于设置图片显示的类

String[] imageUrls; // 图片路径

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ac_image_list);

Bundle bundle = getIntent().getExtras();

imageUrls = bundle.getStringArray(Extra.IMAGES);

// 使用DisplayImageOptions.Builder()创建DisplayImageOptions

options = new DisplayImageOptions.Builder()

.showStubImage(R.drawable.ic_stub) // 设置图片下载期间显示的图片

.showImageForEmptyUri(R.drawable.ic_empty) // 设置图片Uri为空或是错误的时候显示的图片

.showImageOnFail(R.drawable.ic_error) // 设置图片加载或解码过程中发生错误显示的图片

.cacheInMemory(true) // 设置下载的图片是否缓存在内存中

.cacheOnDisc(true) // 设置下载的图片是否缓存在SD卡中

.displayer(new RoundedBitmapDisplayer(20)) // 设置成圆角图片

.build(); // 创建配置过得DisplayImageOption对象

listView = (ListView) findViewById(android.R.id.list);

((ListView) listView).setAdapter(new ItemAdapter());

listView.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

// 点击列表项转入ViewPager显示界面

startImagePagerActivity(position);

}

});

}

@Override

public void onBackPressed() {

AnimateFirstDisplayListener.displayedImages.clear();

super.onBackPressed();

}

private void startImagePagerActivity(int position) {

Intent intent = new Intent(this, ImagePagerActivity.class);

intent.putExtra(Extra.IMAGES, imageUrls);

intent.putExtra(Extra.IMAGE_POSITION, position);

startActivity(intent);

}

/**

  • 自定义列表项适配器

*/

class ItemAdapter extends BaseAdapter {

private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();

private class ViewHolder {

public TextView text;

public ImageView image;

}

@Override

public int getCount() {

return imageUrls.length;

}

@Override

public Object getItem(int position) {

return position;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

View view = convertView;

final ViewHolder holder;

if (convertView == null) {

view = getLayoutInflater().inflate(R.layout.item_list_image, parent, false);

holder = new ViewHolder();

holder.text = (TextView) view.findViewById(R.id.text);

holder.image = (ImageView) view.findViewById(R.id.image);

view.setTag(holder); // 给View添加一个格外的数据

} else {

holder = (ViewHolder) view.getTag(); // 把数据取出来

}

holder.text.setText("Item " + (position + 1)); // TextView设置文本

/**

  • 显示图片

  • 参数1:图片url

  • 参数2:显示图片的控件

  • 参数3:显示图片的设置

  • 参数4:监听器

*/

imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);

return view;

}

}

/**

  • 图片加载第一次显示监听器

  • @author Administrator

*/

private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {

static final List displayedImages = Collections.synchronizedList(new LinkedList());

@Override

public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

if (loadedImage != null) {

ImageView imageView = (ImageView) view;

// 是否第一次显示

boolean firstDisplay = !displayedImages.contains(imageUri);

if (firstDisplay) {

// 图片淡入效果

FadeInBitmapDisplayer.animate(imageView, 500);

displayedImages.add(imageUri);

}

}

}

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageGridActivity.java

网格视图Activity

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

import android.content.Intent;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.GridView;

import android.widget.ImageView;

import com.nostra13.example.universalimageloader.Constants.Extra;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

/**

  • 网格视图显示Activity

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

public class ImageGridActivity extends AbsListViewBaseActivity {

String[] imageUrls; // 图片Url

DisplayImageOptions options; // 显示图片的设置

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ac_image_grid);

Bundle bundle = getIntent().getExtras();

imageUrls = bundle.getStringArray(Extra.IMAGES);

options = new DisplayImageOptions.Builder()

.showStubImage(R.drawable.ic_stub)

.showImageForEmptyUri(R.drawable.ic_empty)

.showImageOnFail(R.drawable.ic_error)

.cacheInMemory(true)

.cacheOnDisc(true)

.bitmapConfig(Bitmap.Config.RGB_565) //设置图片的解码类型

.build();

listView = (GridView) findViewById(R.id.gridview);

((GridView) listView).setAdapter(new ImageAdapter()); // 填充数据

listView.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

startImagePagerActivity(position);

}

});

}

private void startImagePagerActivity(int position) {

Intent intent = new Intent(this, ImagePagerActivity.class);

intent.putExtra(Extra.IMAGES, imageUrls);

intent.putExtra(Extra.IMAGE_POSITION, position);

startActivity(intent);

}

public class ImageAdapter extends BaseAdapter {

@Override

public int getCount() {

return imageUrls.length;

}

@Override

public Object getItem(int position) {

return null;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

final ImageView imageView;

if (convertView == null) {

imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);

} else {

imageView = (ImageView) convertView;

}

// 将图片显示任务增加到执行池,图片将被显示到ImageView当轮到此ImageView

imageLoader.displayImage(imageUrls[position], imageView, options);

return imageView;

}

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImagePagerActivity.java

ViewPager视图Activity

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.os.Parcelable;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ImageView;

import android.widget.ProgressBar;

import android.widget.Toast;

import com.nostra13.example.universalimageloader.Constants.Extra;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

import com.nostra13.universalimageloader.core.assist.FailReason;

import com.nostra13.universalimageloader.core.assist.ImageScaleType;

import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;

import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

/**

  • ViewPager页面显示Activity

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

public class ImagePagerActivity extends BaseActivity {

private static final String STATE_POSITION = “STATE_POSITION”;

DisplayImageOptions options;

ViewPager pager;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ac_image_pager);

Bundle bundle = getIntent().getExtras();

String[] imageUrls = bundle.getStringArray(Extra.IMAGES);

// 当前显示View的位置

int pagerPosition = bundle.getInt(Extra.IMAGE_POSITION, 0);

// 如果之前有保存用户数据

if (savedInstanceState != null) {

pagerPosition = savedInstanceState.getInt(STATE_POSITION);

}

options = new DisplayImageOptions.Builder()

.showImageForEmptyUri(R.drawable.ic_empty)

.showImageOnFail(R.drawable.ic_error)

.resetViewBeforeLoading(true)

.cacheOnDisc(true)

.imageScaleType(ImageScaleType.EXACTLY)

.bitmapConfig(Bitmap.Config.RGB_565)

.displayer(new FadeInBitmapDisplayer(300))

.build();

pager = (ViewPager) findViewById(R.id.pager);

pager.setAdapter(new ImagePagerAdapter(imageUrls));

pager.setCurrentItem(pagerPosition); // 显示当前位置的View

}

@Override

public void onSaveInstanceState(Bundle outState) {

// 保存用户数据

outState.putInt(STATE_POSITION, pager.getCurrentItem());

}

private class ImagePagerAdapter extends PagerAdapter {

private String[] images;

private LayoutInflater inflater;

ImagePagerAdapter(String[] images) {

this.images = images;

inflater = getLayoutInflater();

}

@Override

public void destroyItem(ViewGroup container, int position, Object object) {

((ViewPager) container).removeView((View) object);

}

@Override

public void finishUpdate(View container) {

}

@Override

public int getCount() {

return images.length;

}

@Override

public Object instantiateItem(ViewGroup view, int position) {

View imageLayout = inflater.inflate(R.layout.item_pager_image, view, false);

ImageView imageView = (ImageView) imageLayout.findViewById(R.id.image);

final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);

imageLoader.displayImage(images[position], imageView, options, new SimpleImageLoadingListener() {

@Override

public void onLoadingStarted(String imageUri, View view) {

spinner.setVisibility(View.VISIBLE);

}

@Override

public void onLoadingFailed(String imageUri, View view, FailReason failReason) {

String message = null;

switch (failReason.getType()) { // 获取图片失败类型

case IO_ERROR: // 文件I/O错误

message = “Input/Output error”;

break;

case DECODING_ERROR: // 解码错误

message = “Image can’t be decoded”;

break;

case NETWORK_DENIED: // 网络延迟

message = “Downloads are denied”;

break;

case OUT_OF_MEMORY: // 内存不足

message = “Out Of Memory error”;

break;

case UNKNOWN: // 原因不明

message = “Unknown error”;

break;

}

Toast.makeText(ImagePagerActivity.this, message, Toast.LENGTH_SHORT).show();

spinner.setVisibility(View.GONE);

}

@Override

public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

spinner.setVisibility(View.GONE); // 不显示圆形进度条

}

});

((ViewPager) view).addView(imageLayout, 0); // 将图片增加到ViewPager

return imageLayout;

}

@Override

public boolean isViewFromObject(View view, Object object) {

return view.equals(object);

}

@Override

public void restoreState(Parcelable state, ClassLoader loader) {

}

@Override

public Parcelable saveState() {

return null;

}

@Override

public void startUpdate(View container) {

}

}

}

/2013.8.19_Universal_Image_Loader_Demo/src/com/nostra13/example/universalimageloader/ImageGalleryActivity.java

画廊视图的Activity

/*******************************************************************************

  • Copyright 2011-2013 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.example.universalimageloader;

import android.content.Intent;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.BaseAdapter;

import android.widget.Gallery;

import android.widget.ImageView;

import com.nostra13.example.universalimageloader.Constants.Extra;

import com.nostra13.universalimageloader.core.DisplayImageOptions;

/**

  • 画廊视图Activity

  • @author Sergey Tarasevich (nostra13[at]gmail[dot]com)

*/

@SuppressWarnings(“deprecation”)

public class ImageGalleryActivity extends BaseActivity {

String[] imageUrls;

DisplayImageOptions options;

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.ac_image_gallery);

Bundle bundle = getIntent().getExtras();

imageUrls = bundle.getStringArray(Extra.IMAGES);

options = new DisplayImageOptions.Builder()

.showStubImage(R.drawable.ic_stub)

.showImageForEmptyUri(R.drawable.ic_empty)

.showImageOnFail(R.drawable.ic_error)

.cacheInMemory(true)

.cacheOnDisc(true)

.bitmapConfig(Bitmap.Config.RGB_565)

.build();

// 自API 16之后就被抛弃了

Gallery gallery = (Gallery) findViewById(R.id.gallery);

gallery.setAdapter(new ImageGalleryAdapter());

gallery.setOnItemClickListener(new OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

startImagePagerActivity(position);

}

});

}

private void startImagePagerActivity(int position) {

Intent intent = new Intent(this, ImagePagerActivity.class);

intent.putExtra(Extra.IMAGES, imageUrls);

intent.putExtra(Extra.IMAGE_POSITION, position);

startActivity(intent);

}

private class ImageGalleryAdapter extends BaseAdapter {

@Override

public int getCount() {

return imageUrls.length;

}

@Override

public Object getItem(int position) {

return position;

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

ImageView imageView = (ImageView) convertView;

if (imageView == null) {

imageView = (ImageView) getLayoutInflater().inflate(R.layout.item_gallery_image, parent, false);

}

imageLoader.displayImage(imageUrls[position], imageView, options);

return imageView;

}

}

}

关于桌面控件的代码我就不贴了,朋友们可以自己下载我这个Demo

还有就是Manifest文件代码

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

关于面试的充分准备

一些基础知识和理论肯定是要背的,要理解的背,用自己的语言总结一下背下来。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,我能明显感觉到国庆后多了很多高级职位,所以努力让自己成为高级工程师才是最重要的。

好了,希望对大家有所帮助。

接下来是整理的一些Android学习资料,有兴趣的朋友们可以关注下我免费领取方式

①Android开发核心知识点笔记

②对标“阿里 P7” 40W+年薪企业资深架构师成长学习路线图

③面试精品集锦汇总

④全套体系化高级架构视频

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

ayout.item_gallery_image, parent, false);

}

imageLoader.displayImage(imageUrls[position], imageView, options);

return imageView;

}

}

}

关于桌面控件的代码我就不贴了,朋友们可以自己下载我这个Demo

还有就是Manifest文件代码

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-hFAsK3xZ-1712345981702)]

[外链图片转存中…(img-YH15ERn7-1712345981702)]

[外链图片转存中…(img-QMiL3UG5-1712345981703)]

[外链图片转存中…(img-ll1bqu9M-1712345981703)]

[外链图片转存中…(img-sAZv0JpG-1712345981703)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

关于面试的充分准备

一些基础知识和理论肯定是要背的,要理解的背,用自己的语言总结一下背下来。

虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,我能明显感觉到国庆后多了很多高级职位,所以努力让自己成为高级工程师才是最重要的。

好了,希望对大家有所帮助。

接下来是整理的一些Android学习资料,有兴趣的朋友们可以关注下我免费领取方式

①Android开发核心知识点笔记

②对标“阿里 P7” 40W+年薪企业资深架构师成长学习路线图

[外链图片转存中…(img-TP3wSRCJ-1712345981703)]

③面试精品集锦汇总

[外链图片转存中…(img-DfSSImyt-1712345981704)]

④全套体系化高级架构视频

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

[外链图片转存中…(img-JaEDN1N6-1712345981704)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值