自定义ListView使用Volley获取数据"/>
自定义ListView使用Volley获取数据
这是作为Volley框架使用的练习,如果对Volley框架的使用还不太熟悉,
建议先看前三篇文章:Android Volley的使用(一)
Android Volley的使用(二)
Android Volley的使用(三)
本文代码github地址:UseVolley
要实现的效果如下:
Tips:以下大多数代码都是前三篇文章中详细介绍过的,在这里作为练习只提供一种思路,不再赘述
1,将Volley.jar添加进项目
获取Volley:
- git clone 的方式
或者
你也可以直接下载 volley.jar如果你是通过git clone方式,为了生成
voller.jar
你需要在你clone的volley目录下执行:android update project -pant jar
将Volley添加进项目:
- 将
volley.jar
粘贴进libs
文件夹下,然后右键volley.jar
文件,选择Add as Library
2,创建ApplictionController类
public class ApplicationController extends Application {private static final String TAG= ApplicationController.class.getSimpleName();private RequestQueue requestQueue;private ImageLoader imageLoader;private static ApplicationController mInstance;@Overridepublic void onCreate() {super.onCreate();mInstance=this;}public static synchronized ApplicationController getInstance(){return mInstance;}public RequestQueue getRequestQueue(){if(requestQueue==null)requestQueue= Volley.newRequestQueue(getApplicationContext());return requestQueue;}public ImageLoader getImageLoader(){getRequestQueue();if(imageLoader==null){imageLoader=new ImageLoader(requestQueue,new LruBitmapCache());}return imageLoader;}public <T> void addToRequestQueue(Request<T> req,String tag){req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);getRequestQueue().add(req);}public <T> void addToRequestQueue(Request<T> req){req.setTag(TAG);getRequestQueue().add(req);}public void cancelPendingRequest(Object tag){if(requestQueue!=null){requestQueue.cancelAll(tag);}}}
3,创建LruBitmapCache类
public class LruBitmapCache extends LruCache<String,Bitmap> implements ImageLoader.ImageCache {public static int getDefaultLruCacheSize(){final int maxMemory= (int) (Runtime.getRuntime().maxMemory()/1024);final int cacheSize=maxMemory/8;return cacheSize;}public LruBitmapCache(){this(getDefaultLruCacheSize());}public LruBitmapCache(int sizeInKiloBytes) {super(sizeInKiloBytes);}@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getRowBytes() * value.getHeight() / 1024;}@Overridepublic Bitmap getBitmap(String url) {return get(url);}@Overridepublic void putBitmap(String url, Bitmap bitmap) {put(url, bitmap);}
}
4,Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android=""package="com.coder.usevolley" ><uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><application
android:name=".ApplicationController"android:allowBackup="true"android:icon="@mipmap/icon_movie"android:label="@string/app_name"android:theme="@style/AppTheme" ><activity
android:icon="@mipmap/icon_movie"android:name=".MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
以下这部分主要涉及如何自定义ListView视图,自定义Adapter
5,布局文件
activity_main.xml
中添加一个ListView
<LinearLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"><ListView
android:id="@+id/movie_list"android:divider="#cccdde"android:dividerHeight="1dp"android:layout_width="match_parent"android:layout_height="wrap_content"></ListView></LinearLayout>
ListView中Item的视图:
在layout文件夹下创建movie_list_item.xml
这里的ImageView用的是Volley中的NetworkImageView,当然也可以直接用ImageView,二者稍有区别,详见Android Volley的使用(三)
布局我们可以采用RelativeLayout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""android:padding="8dp"android:layout_width="match_parent"android:layout_height="wrap_content"><com.android.volley.toolbox.NetworkImageView
android:id="@+id/movie_image"android:layout_alignParentLeft="true"android:layout_marginRight="8dp"android:layout_width="80dp"android:layout_height="80dp" /><TextView
android:id="@+id/movie_name"android:layout_toRightOf="@+id/movie_image"android:layout_alignTop="@+id/movie_image"android:layout_marginTop="1dp"android:textSize="15sp"android:textStyle="bold"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextView
android:id="@+id/movie_rating"android:textColor="#f243"android:textSize="13sp"android:layout_marginTop="5dp"android:layout_below="@+id/movie_name"android:layout_toRightOf="@+id/movie_image"android:layout_width="match_parent"android:layout_height="wrap_content" /><TextView
android:id="@+id/movie_year"android:textColor="#aaa"android:textSize="10sp"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_width="wrap_content"android:layout_height="wrap_content" /></RelativeLayout>
6,定义数据模型:Movie
由于这里需要用数据请求,因此我创建了一个关于电影的Json数据movies.json,至于json数据的创建和服务端不是这次的内容,故不再说明,有兴趣的同学自己去了解。返回的数据格式如下:
所以我们需要定义一个movie类:
public class Movie {private String name;private String rating;private String image;private String year;public void setName(String name) {this.name = name;}public void setRating(String rating) {this.rating = rating;}public void setImage(String imageUrl) {this.image = imageUrl;}public void setYear(String year) {this.year = year;}public String getName() {return name;}public String getRating() {return rating;}public String getYear() {return year;}public String getImage() {return image;}public Movie(){}public Movie(String name,String rating,String imageUrl,String year){this.name=name;this.rating=rating;this.image=imageUrl;this.year=year;}}
7,自定义适配器类:MovieAdapter
我们需要将数据中的内容填充到ListView的Item中,即movie_list_item布局中,所以需要自定义适配器类:覆写其中的方法,getView()方法控制显示的视图
public class MovieAdapter extends BaseAdapter {private ArrayList<Movie> movies;private Activity activity;private LayoutInflater inflater;private ImageLoader imageLoader;private NetworkImageView movieImage;private TextView movieName,movieYear,movieRating;public MovieAdapter() {super();}public MovieAdapter(Activity activity,ArrayList<Movie> movies) {this.activity=activity;this.movies=movies;}@Overridepublic int getCount() {return movies.size();}@Overridepublic Object getItem(int i) {return movies.get(i);}@Overridepublic long getItemId(int i) {return i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {if (inflater == null)inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);if (view == null)view = inflater.inflate(R.layout.movie_list_item, null);if (imageLoader == null)imageLoader = ApplicationController.getInstance().getImageLoader();movieImage= (NetworkImageView) view.findViewById(R.id.movie_image);movieName= (TextView) view.findViewById(R.id.movie_name);movieRating= (TextView) view.findViewById(R.id.movie_rating);movieYear= (TextView) view.findViewById(R.id.movie_year);movieImage.setImageUrl(movies.get(i).getImage(),imageLoader);movieName.setText((CharSequence) movies.get(i).getName());movieRating.setText("Rating:"+(CharSequence) movies.get(i).getRating());movieYear.setText((CharSequence) movies.get(i).getYear());return view;}
}
8,MainActivity
这部分才是我们需要真正实践Volley代码的部分
public class MainActivity extends ActionBarActivity {private static final String TAG=MainActivity.class.getSimpleName();private ArrayList<Movie> movies;private MovieAdapter adapter;private ListView movieList;private static final String url=".json";private ProgressDialog pDialog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);movieList= (ListView) findViewById(R.id.movie_list);pDialog=new ProgressDialog(this);pDialog.setMessage("Loading...");pDialog.show();movies=new ArrayList<Movie>();fetchMovies();adapter=new MovieAdapter(MainActivity.this,movies);movieList.setAdapter(adapter);}private void fetchMovies() {JsonArrayRequest req=new JsonArrayRequest(url, new Response.Listener<JSONArray>() {@Overridepublic void onResponse(JSONArray jsonArray) {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {hidePDialog();}},1000);for(int i=0;i<jsonArray.length();i++){try {JSONObject object=jsonArray.getJSONObject(i);Movie movie=new Movie();movie.setImage(object.getString("image"));movie.setName(object.getString("name"));movie.setRating(object.getString("rating"));movie.setYear(object.getString("year"));movies.add(movie);} catch (JSONException e) {e.printStackTrace();}}//注意刷新数据adapter.notifyDataSetChanged();}}, new Response.ErrorListener() {@Overridepublic void onErrorResponse(VolleyError volleyError) {Log.e(TAG,"error:"+volleyError.getMessage());hidePDialog();}});ApplicationController.getInstance().addToRequestQueue(req);}public void hidePDialog(){if(pDialog!=null)pDialog.dismiss();pDialog=null;}@Overrideprotected void onDestroy() {super.onDestroy();hidePDialog();}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);return true;}}
总结:
上面的很多代码都是我们在学习Volley框架中实现过的,所以只要正在掌握了Volley,以后使用的时候是很容易的,至于自定义ListView部分不太熟悉的可以参考下面这篇文章,有学Android小伙伴加微信共同进步哦~
参考资料:Android working with Volley Library
- 微博: @明桑Android黑历史
- 邮箱: <13141459344@163>
个人主页: 明桑战胜Android汪的黑历史
更多推荐
自定义ListView使用Volley获取数据
发布评论