ListView 是手机系统上应用非常非常广泛的一种组件,它以垂直列表的形式显示所有列表项。

一、怎样去布局ListView

ListView额外提供如图以下的xml属性:



android:divider="#000"设置分割条为纯黑色

android:dividerHeight="3sp" 设置分割条高度为3dp

android:divider="@drawable/news_test1" 设置分割条为图片news_test1 

android:entries="@array/books" 指定books列表数组,还需在应用中定义一个名为books的数组,一般是提供Adapter


布局ListView的一个条目item的布局:当布局好ListView之后,可以根据需要对每个条目进行布局,以新闻的条目为例如下:




条目中的初始数据可以假设初设定。当代码进行操作后,会产生如下布局:




android listview 循环滚动 listview控件的滚动用法_android



在条目上分别设有图片、新闻题目、新闻内容简介。



二、代码组成和适配器Adapter


先看下代码:


package com.itheima.news_listview.adapter;

import java.util.ArrayList;

import com.itheima.news_listview.R;
import com.itheima.news_listview.bean.NewsBean;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class NewsAdapter extends BaseAdapter {
	
	private ArrayList
    
    
     
      list;
	private Context context;

	public NewsAdapter(Context context,ArrayList
     
     
      
       list){
		this.list = list;
		this.context = context;
	}

	@Override
	public int getCount() {
		return list == null?0:list.size();
	}

	@Override
	public Object getItem(int position) {
		return list.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		Log.i("TAG", "$$$$$$$$$$$$"+position);
		View view = null;
		if(convertView != null){
			view = convertView;
		}else {
			LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			view = layoutInflater.inflate(R.layout.item_news_layout, null);
			
		}
		//获取子控件的对象
		ImageView item_img_icon = (ImageView) view.findViewById(R.id.item_img_icon);
		TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des);
		TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title);
//		获取postion位置的对应list集合中的新闻数据
		NewsBean newsBean = list.get(position);
		//设置标题
		item_tv_title.setText(newsBean.title);
		//设置内容
		item_tv_des.setText(newsBean.des);
		
		item_img_icon.setImageDrawable(newsBean.icon);
		
		return view;
	}

}



先讲ListView和Adapter怎样工作的:


每当有一个条目暴露在屏幕下,adapter适配器就会为这个条目创建出item布局。每次滑动就会把新暴露出来的条目进行加载。在代码中添加的打印:Log.i("TAG", "$$$$$$$$$$$$创建的条目个数为:"+position);如果当前代码如下:


public View getView(int position, View convertView, ViewGroup parent) {
		Log.i("TAG", "$$$$$$$$$$$$创建的条目个数为:"+position);
		View view = null;
//		if(convertView != null){
//			view = convertView;
//		}else {
			LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			view = layoutInflater.inflate(R.layout.item_news_layout, null);
			
		//}
		//获取子控件的对象
		ImageView item_img_icon = (ImageView) view.findViewById(R.id.item_img_icon);
		TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des);
		TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title);
//		获取postion位置的对应list集合中的新闻数据
		NewsBean newsBean = list.get(position);
		//设置标题
		item_tv_title.setText(newsBean.title);
		//设置内容
		item_tv_des.setText(newsBean.des);
		
		item_img_icon.setImageDrawable(newsBean.icon);
		
		return view;
	}
}


android listview 循环滚动 listview控件的滚动用法_ide_02


创建太多的条目,占用运行资源。但是,如果有1万条条目时,不可能去全部加载出来。故会添加一个判断,复用已经完全消失在屏幕的条目进行复用,只会产生屏幕显示的条目个数+1(头一个没有完成消失,新暴露出来的已经加载,固此处要+1),代码如下:


public View getView(int position, View convertView, ViewGroup parent) {
		Log.i("TAG", "$$$$$$$$$$$$创建的条目个数为:" + position);
		View view = null;
		if (convertView != null) {
			view = convertView;
		} else {
			LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			view = layoutInflater.inflate(R.layout.item_news_layout, null);

		}
		// 获取子控件的对象
		ImageView item_img_icon = (ImageView) view.findViewById(R.id.item_img_icon);
		TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des);
		TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title);
		// 获取postion位置的对应list集合中的新闻数据
		NewsBean newsBean = list.get(position);
		// 设置标题
		item_tv_title.setText(newsBean.title);
		// 设置内容
		item_tv_des.setText(newsBean.des);

		item_img_icon.setImageDrawable(newsBean.icon);

		return view;
	}
}


这样会把复用view=converView。



BaseAdapter的四个方法实现:


适配器的使用必须要实现4个方法,现在分别介绍4个方法的代表含义:



public int getCount() { 
  
return list == null ? 0 : list.size();   
 }

有多少个项目放在适配器的数据中。返回一个int类型的数,此处返回一个数字的个数,但要用三目算法判断下数字是否为空。必须要判断下。




public Object getItem(int position) {
return list.get(position);
 }


得到相关的数据项的指定位置的数据集,一般指对象数组的元素内容。返回一个Obj类型,此次数组存放的为对象




public long getItemId(int position) {
return position;
 }


得到相关的行id列表中指定的位置 指item的id  返回一个long型




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


//得到一个视图显示数据集的数据在指定的位置。你可以手动创建一个视图或指定XML布局文件。


返回一个View布局的展示,这里要设置引入布局的各项参数

View view = null;
if (convertView != null) {
view = convertView;
//复用convertView
} else {
LayoutInflater layoutInflater = (LayoutInflater)                                  context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
view = layoutInflater.inflate(R.layout.item_news_layout, null); 
//引用自己设定的xml布局格式
}
// 获取子控件的对象
ImageView item_img_icon = (ImageView) view.findViewById(R.id.item_img_icon); 
//拿到图片
TextView item_tv_des = (TextView) view.findViewById(R.id.item_tv_des); 
//拿到新闻内容
TextView item_tv_title = (TextView) view.findViewById(R.id.item_tv_title);
 //拿到新闻题目
// 获取postion位置的对应list集合中的新闻数据
NewsBean newsBean = list.get(position);
// 设置标题
item_tv_title.setText(newsBean.title);
// 设置内容
item_tv_des.setText(newsBean.des); 
// 设置图片
item_img_icon.setImageDrawable(newsBean.icon);
//显示当前条目内容
return view;
}


4个方法是关键,大部分是固定格式。




创建适配器和条目的点击监控:


先看主方法的代码:


package com.itheima.news_listview;

import java.util.ArrayList;

import com.itheima.news_listview.adapter.NewsAdapter;
import com.itheima.news_listview.bean.NewsBean;
import com.itheima.news_listview.utils.NewsUtils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class MainActivity extends Activity implements OnItemClickListener {

	private Context mContext;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = this;
		//找到控件
		ListView lv_news = (ListView) findViewById(R.id.lv_news);
		ArrayList
    
    
     
      allNews = NewsUtils.getAllNews(mContext);
		//创建适配器adapter,把当前上下文和新闻资源传递
		NewsAdapter newsAdapter = new NewsAdapter(mContext, allNews);
		lv_news.setAdapter(newsAdapter);
//		设置条目的点击事件
		lv_news.setOnItemClickListener(this);				
	}
	@Override
	public void onItemClick(AdapterView
     
      parent, View view, int position,
			long id) {
		
		NewsBean bean = (NewsBean) parent.getItemAtPosition(position);
		
		String url = bean.news_url;
		
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.setData(Uri.parse(url));
		startActivity(intent);
	}
}


监控方法中有监控条目的方法,直接使用就行:


public void onItemClick(AdapterView<?> parent, View view, int position, 
  
long id) {   
点击后需要执行的操作     
  
}


滚动条的用法和属性:



当文字很多时View的高度不能超过一个固定的值,无法满足需求,因为ScrollView没有maxHeight,所以要了解其用法。


虽然Textview里面有方法可以实现该功能。如下:


<TextView    android:id="@+id/text_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:singleLine="false"
    android:maxLines="10"
    android:scrollbars="vertical"/>

但还有在java中设定:


TextView textView = (TextView)findViewById(R.id.text_view); 
 textView.setMovementMethod(ScrollingMovementMethod.getInstance());




上述方法需要在两个部分设定,过于麻烦,现在可以直接用ScrollView来实现滚动:代码如下:


<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv_source"/>
</ScrollView>

也可以设定在横向的滚动HorizontalScrollView 代码如下

<HorizontalScrollView
        
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >       
      <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_source"/>
     </HorizontalScrollView>



也可以同时使用,外面套一层垂直的ScrollView就行,代码如下:


<ScrollView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
    <HorizontalScrollView
        
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >
        
        <TextView 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_source"/>
     </HorizontalScrollView>
    </ScrollView>
总结:需要掌握Adapter的4个方法,和设置item的点击事件。
学会布局ListView 和item的布局