标签:volley listview android android网络 自定义adapter
这是作为Volley框架使用的练习,如果对Volley框架的使用还不太熟悉,
建议先看前三篇文章:本文代码github地址:UseVolley
要实现的效果如下:
Tips:以下大多数代码都是前三篇文章中详细介绍过的,在这里作为练习只提供一种思路,不再赘述
获取Volley:
https://android.googlesource.com/platform/frameworks/volley
或者https://github.com/mcxiaoke/android-volley
你也可以直接下载 volley.jar
如果你是通过git clone方式,为了生成voller.jar
你需要在你clone的volley目录下执行:
android update project -p
ant jar
将Volley添加进项目:
volley.jar
粘贴进libs
文件夹下,然后右键volley.jar
文件,选择Add as Librarypublic class ApplicationController extends Application {
private static final String TAG= ApplicationController.class.getSimpleName();
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static ApplicationController mInstance;
@Override
public 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);
}
}
}
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);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/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
activity_main.xml
中添加一个ListView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/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="http://schemas.android.com/apk/res/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>
由于这里需要用数据请求,因此我创建了一个关于电影的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;
}
}
我们需要将数据中的内容填充到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;
}
@Override
public int getCount() {
return movies.size();
}
@Override
public Object getItem(int i) {
return movies.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public 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;
}
}
这部分才是我们需要真正实践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="http://www.jycoder.com/json/movies.json";
private ProgressDialog pDialog;
@Override
protected 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>() {
@Override
public void onResponse(JSONArray jsonArray) {
new Handler().postDelayed(new Runnable() {
@Override
public 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() {
@Override
public 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;
}
@Override
protected void onDestroy() {
super.onDestroy();
hidePDialog();
}
@Override
public 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汪的黑历史
标签:volley listview android android网络 自定义adapter
原文地址:http://blog.csdn.net/qwm8777411/article/details/45833903