1、HeaderView,FooterView,EmptyView的使用
示例代码:
public class MainActivity extends AppCompatActivity {
private ListView listView;
private List<View> headerViewList = new LinkedList<>();
private List<View> footerViewList = new LinkedList<>();
private List<Message> data = new ArrayList<>();
private BaseAdapter adapter = new MessageAdapter(this, data);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
fillData(data);
View headerView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.header_view, listView, false);
listView.addHeaderView(headerView);
//addHeaderView必须在setAdapter之前
headerViewList.add(headerView);
adapter = new MessageAdapter(this, data);
listView.setAdapter(adapter);
// View emptyView = findViewById(R.id.empty_view);
//设置EmptyView
ViewGroup listViewContainer = (ViewGroup) findViewById(R.id.listview_container);
View emptyView = LayoutInflater.from(this).inflate(R.layout.empty_view, listViewContainer, false);
listViewContainer.addView(emptyView);
listView.setEmptyView(emptyView);
//设置headerView
Button addHeader = (Button) findViewById(R.id.add_header);
addHeader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View headerView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.header_view, listView, false);
listView.addHeaderView(headerView);
headerViewList.add(headerView);
}
});
//设置FooterView
Button removeHeader = (Button) findViewById(R.id.remove_header);
removeHeader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (headerViewList.size() > 0) {
listView.removeHeaderView(headerViewList.get(0));
headerViewList.remove(0);
}
}
});
//添加footerView
Button addFooter = (Button) findViewById(R.id.add_footer);
addFooter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View footerView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.footer_view, listView, false);
listView.addFooterView(footerView);
footerViewList.add(footerView);
}
});
//移除footerView
Button removeFooter = (Button) findViewById(R.id.remove_footer);
removeFooter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (footerViewList.size() > 0) {
listView.removeFooterView(footerViewList.get(0));
footerViewList.remove(0);
}
}
});
Button clearData = (Button) findViewById(R.id.clear_data);
clearData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
data.clear();
adapter.notifyDataSetChanged();
}
});
Button restoreData = (Button) findViewById(R.id.restore_data);
restoreData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
data.clear();
fillData(data);
adapter.notifyDataSetChanged();
}
});
}
private void fillData(List<Message> data) {
for (int i = 0; i < 100; i++) {
data.add(new Message("我是文本消息" + i));
}
}
}
2、OnItemClickListener
调用了addHeaderView,或addFooterView之后,想要获取listView上某个点击项的内容时:
(1)若调用
Object item=data.get(position);
此时的position,因为之前addHeader已不准确。
(2)若调用
Object item=adapter.getItem(position);
若之前调用了addHeaderView,HeaderViewListAdapter会把HeaderView,FooterView,ListAdapter封装成一个HeaderViewListAdapter。已经不是之前调用的adapter。此方法也不行。
(3)建议调用
Object item=parent.getItemAtPosition(position);
示例测试代码:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getName();
private ListView listView;
private BaseAdapter adapter;
private List<Message> data;
private List<View> headerViewList = new LinkedList<>();
private List<View> footerViewList = new LinkedList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add(new Message("我是文本消息" + i));
}
adapter = new MessageAdapter(this, data);
listView.setAdapter(adapter);
Button addHeader = (Button) findViewById(R.id.add_header);
addHeader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View headerView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.header_view, listView, false);
listView.addHeaderView(headerView);
headerViewList.add(headerView);
}
});
Button addFooter = (Button) findViewById(R.id.add_footer);
addFooter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View footerView = LayoutInflater
.from(MainActivity.this)
.inflate(R.layout.footer_view, listView, false);
listView.addFooterView(footerView);
footerViewList.add(footerView);
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String tip = "position:" + position
+ "\nid:" + id
+ "\nparent.getItemAtPosition:" + parent.getItemAtPosition(position);
Log.i(TAG, tip);
}
});
}
}
listView中的焦点冲突
若listView中item中的子控件是focusable,那click事件就不会传递到item中。
解决办法
(1)设置子控件为focusable=fale;
(2)设置item布局
android:descendantFocusability="blocksDescendants"
API>=5.0
android:touchscreenBlocksFocus="true"
4、滑动状态
示例代码
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.i("listener",
"onScrollStateChanged scrollState:" + scrollState);
switch (scrollState){
case SCROLL_STATE_IDLE:
//停止滑动
break;
case SCROLL_STATE_FLING:
//手指还停留在屏幕上,listView随着手指的滑动而滑动
break;
case SCROLL_STATE_TOUCH_SCROLL:
//手指已离开屏幕,listView还在随着惯性滑动
break;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//是否滑动到底部
if (firstVisibleItem + visibleItemCount == totalItemCount) {
Toast.makeText(
MainActivity.this,
"自动加载新数据",
Toast.LENGTH_SHORT).show();
int count = data.size();
for (int i = count; i < count + 100; i++) {
data.add(new Message("我是文本消息" + i));
}
adapter.notifyDataSetChanged();
}
}
});