BaseAdapter是实现了ListAdapter和SpinnerAdapter两个接口,当
然它也可以直接给ListView和Spinner等UI组件直接提供数据。
BaseAdapter的需要重写四个方法:
1、getCount()决定了我们将要绘制的资源数,当然这个数目不能大于资源的总数,不过却可以小于资源的总数。
2、getItemId()该方法的返回值决定第position处的列表项的ID,某些方法(如onclicklistener的onclick方法)有id这个参 数,而这个id参数就是取决于getItemId()这个返回值的。
3、getView():通过传入的参数position,加工成我们想要的View并返回,最终共GridView使用
4、getItem():getItem方法不是在Baseadapter类中被调用的,而是在Adapterview.getItemAtPosition(position) 中被调用的。getItemAtPosition(position) 是在setOnItemClickListener、setOnItemLongClickListener、setOnItemSelectedListener的点击选择处理事件中方便地调用来获取当前行数据的。
1、对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入.
2、对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方法来获得其中的界面元素.
作用及使用场景:后台线程执行异步任务,将result告知UI线程;子线程和主线程(UI线程)需要通讯的时候,可以使用AsyncTask
使用方法:
1.创建 AsyncTask 的子类,并为三个泛型参数指定类型。不需要则可指定Void。
Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的。
Progress:子线程执行的百分比。
Result:返回值类型。和doInBackground()方法的返回值类型保持一致。
2.根据需要,实现 AsyncTask 的如下方法:
doInBackground(Params…)重写该方法就是后台线程将要完成的任务。该方法可调用 publishProgress(Progress… values)方法更新任务的执行进度。
onProgressUpdate(Progress… values)在doInBackground() 方法中调用publishProgress()方法更新任务的执行进度后,该方法被触发。
onPreExecute() :该方法将在执行后台耗时操作前被调用。通常用于完成一些初始化的准备工作,比如在界面上显示进度条。
onPostExecute(Result result) :当 doInBackground() 完成后,系统会自动调用该方法,并将 doInBackground() 的返回值传给该方法。
3.调用 AsyncTask 子类的实例的 execute(Params… params) 开始执行耗时任务。
使用AsyncTask 时必须遵守如下规则:
必须在 UI 线程中创建 AsyncTask 的实例。
必须在 UI 线程中调用 AsyncTask 的 execute() 方法。
AsyncTask的实例只能启动一次(若要多次调用,则每次调用都需要新创建一个AsyncTask实例)
1、创建一个自定义的BaseAdapter : MyBaseAdapter 类,继承BaseAdapter,重写四个方法
public class MyBaseAdapter extends BaseAdapter {
// 声明变量,供getCount和getView使用
Context context;
List data;
LayoutInflater inflater;// 用来实现对页面的动态载入
public MyBaseAdapter(Context context, List data) {
this.context = context;
this.data = data;
// 载入传递过来的Activity,这里是载入MainActivity.class
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return data.get(position).id;
}
// getView:返回每一个Item的View
// 步骤:
/* * 1.写一个内部类ViewHolder,用来保存需要设置值的控件(以空间换时间) * 2.在getView方法中,声明一个ViewHolder对象,并置为null * 3.根据convertView是否为null,决定是否创建新的View还是复用View * 4.如果是创建新的View,利用LayoutInflater把xml文件转换成View,并赋值给convertView * 创建一个新的ViewHoder,并对ViewHoder中的控件进行初始化 把创建的ViewHoder关联到convertView * 5.如果是复用的View,说明已经有ViewHoder与convertView进行关联过,直接取出对应的Tag * 6.对ViewHoder中的控件进行赋值 */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 创建ViewHoder对象
Viewhondler hondler = null;
// 根据convertView判断是否创建新的View
if (convertView == null) {
hondler = new Viewhondler();
// 通过inflate方法来载入layout的xml
convertView = inflater.inflate(R.layout.my_listview_item, null);
hondler.tv_id = (TextView) convertView.findViewById(R.id.tv_id);
hondler.tv_author = (TextView) convertView
.findViewById(R.id.tv_author);
hondler.tv_content = (TextView) convertView
.findViewById(R.id.tv_content);
hondler.iv = (ImageView) convertView.findViewById(R.id.img);
// 把hoder与convertView关联
convertView.setTag(hondler);
} else {
// 已经有可用视图,说明已经有holder与convertView进行关联过,取出Tag,并赋值给holder对象
hondler = (Viewhondler) convertView.getTag();
}
// 给各个控件设置初始值,解决图片错位等问题
hondler.iv.setImageResource(R.drawable.ic_launcher);
hondler.tv_author.setText("");
hondler.tv_content.setText("");
hondler.tv_id.setText("");
// 取消前面的下载任务,要在新下载任务启动之前先取消
if (hondler.task != null) {
hondler.task.cancel(true);
}
// 给相应控件设置值
JokeBean bean = data.get(position);
hondler.tv_id.setText("id:" + bean.id);
hondler.tv_author.setText("作者:" + bean.author);
hondler.tv_content.setText(bean.content);
DownLoadImage task = new DownLoadImage(hondler.iv);
hondler.task = task;
task.execute(bean.picUrl);
// 返回设置好的值的View
return convertView;
}
class Viewhondler {
DownLoadImage task;// 图片下载任务
TextView tv_id;
TextView tv_xhid;
TextView tv_author;
TextView tv_content;
ImageView iv;
}
}
2、通过异步从网络上下载数据
MyTask .class 继承了AsyncTask,里面自定义了MyCallBack接口,用于接口回调传回下载后的数据。
public class MyTask extends AsyncTask<String, Void, List<JokeBean>> { interface MyCallBack{ public void getData(List list); } MyCallBack cb; public MyTask(MyCallBack cb) { super(); this.cb = cb; } @Override protected List doInBackground(String... params) { try { String str = HttpUtils.getStringByHttp(params[0]); List jokeBeans = HttpUtils.getJokeBeans(str); return jokeBeans; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onPostExecute(List result) { // TODO Auto-generated method stub super.onPostExecute(result); cb.getData(result); } }
3、通过异步实现图片的下载并设置到ImageView上:
/** * 通过异步实现图片的下载 * */
public class DownLoadImage extends AsyncTask<String, Void, Bitmap> {
ImageView iv;
public DownLoadImage(ImageView iv) {// 接收传递过来的ImageView控件
this.iv = iv;
}
@Override
protected Bitmap doInBackground(String... params) {
try {
// 调用HttpUtils的getBitmapByHttp()方法联网下载图片
Bitmap bitmap = HttpUtils.getBitmapByHttp(params[0]);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// 下载完成后得到Bitmap,给ImageView设置值,判断当前任务是否被取消,如果当前任务被取消,就不再设置图片,
//避免异步加载时图片连闪和错位问题
if (result != null && !isCancelled()) {
iv.setImageBitmap(result);
}
}
}
4、下载工具类
/** * 下载工具类 * */
public class HttpUtils {
public static String getStringByHttp(String http) throws Exception {
HttpURLConnection connection = null;
URL url = new URL(http);
connection = (HttpURLConnection) url.openConnection();
InputStream in = connection.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String temp = null;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
connection.disconnect();
return sb.toString();
}
public static List getJokeBeans(String str) throws JSONException {
ArrayList data = new ArrayList();
JSONObject object = new JSONObject(str);
JSONArray arr = object.getJSONArray("detail");
int len = arr.length();
for (int i = 0; i < len; i++) {
JSONObject obj = arr.getJSONObject(i);
JokeBean bean1 = new JokeBean();
bean1.id = obj.getInt("id");
bean1.xhid = obj.getInt("xhid");
bean1.author = obj.getString("author");
bean1.content = obj.getString("content");
bean1.picUrl = obj.getString("picUrl");
data.add(bean1);
}
return data;
}
public static Bitmap getBitmapByHttp(String http) throws Exception {
HttpURLConnection conn = null;
URL url = new URL(http);
conn = (HttpURLConnection) url.openConnection();
InputStream in = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
in.close();
conn.disconnect();
return bitmap;
}
}
5、MainActivity类,主入口
public class MainActivity extends Activity {
private ListView lv;
private MyBaseAdapter adapter;
private List data;
Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
initData();
}
private void initData() {
data = new ArrayList();
adapter = new MyBaseAdapter(this,data);
lv.setAdapter(adapter);
MyTask task = new MyTask(new MyCallBack() {
@Override
public void getData(List list) {
data.addAll(list);
adapter.notifyDataSetChanged();
}
});
task.execute("http://api.1-blog.com/biz/bizserver/xiaohua/list.do?size=200&page=5");
}
}
<uses-permission android:name="android.permission.INTERNET"/>
6、布局:my_listview_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<TextView android:id="@+id/tv_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="20sp" />
<TextView android:id="@+id/tv_author" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="25sp" />
<TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/input_over" android:textSize="20sp" />
<ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:src="@drawable/ic_launcher" />
LinearLayout>
activity_main.xml
"http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="ljw.day009_night_baseadapter.MainActivity" >
"@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>