最近在学习ViewPager,想实现对ViewPager进行动态添加和删除,结果遇到各种问题。仅以此篇博客记录此过程和出现问题的一些解决方法。
最初想实现的效果是一个页面用来接收输入的内容并显示在ListView上,同时在当前页前添加一个页面显示输入的文本内容。最后写了半天实现不了,只好退而求其次,在当前页后添加内容。布局文件如下。
activity_main.xml:
<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"
android:gravity="center"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
以上是很简单的布局,就是一个ViewPager。
activity_citylist.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/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="北京"
android:textSize="20sp"
android:textColor="#ff00aa"
/>
</LinearLayout>
以上是listView填充的布局 。
MainActivity.java:
package com.example.viewpager;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
/**
* @author Administrator
*
*/
public class MainActivity extends Activity {
private ViewPager vpager_one;
private ArrayList<View> aList;
private MyPageAdapter mAdapter;
private ListView mListView;
private ArrayList<String> mCity;
private Button mAdd;
private Context mContext;
private MyAdapter mListAdapter;
private EditText mInCityName;
private ListView lv;
private View view1;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
initView();
mListAdapter = new MyAdapter(mContext, mCity);
mAdapter = new MyPageAdapter(aList);
vpager_one.setAdapter(mAdapter);
lv.setAdapter(mListAdapter);
/**
* @author Administrator
*在listview长按事件,响应弹出删除对话框
*
*
*/
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
private int position;
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
this.position = position;
// TODO Auto-generated method stub\
AlertDialog.Builder builder = new AlertDialog.Builder(
MainActivity.this);
// 设置Title的图标
builder.setIcon(R.drawable.ic_launcher);
// 设置Title的内容
builder.setTitle("弹出警告框");
// 设置Content来显示一个信息
builder.setMessage("确定删除吗?");
// 设置一个PositiveButton
builder.setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
mCity.remove(position);
mListAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this,
"positive: " + position,
Toast.LENGTH_SHORT).show();
System.out.println(position);
// 因为从第二页开始删起,所以position需要加一
removeItem(position + 1);
}
});
// 设置一个NegativeButton
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
// Toast.makeText(MainActivity.this,
// "negative: " + which,
// Toast.LENGTH_SHORT).show();
}
});
builder.show();
return false;
}
});
vpager_one.setCurrentItem(0);
vpager_one.setOnPageChangeListener(new MyOnPageChangeListener());
mAdd.setOnClickListener(new View.OnClickListener() {
/**
* @author Administrator
*添加listview的内容和页卡
*/
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCity.add(mInCityName.getText().toString());
System.out.println(mInCityName.getText().toString());
mListAdapter.notifyDataSetChanged();//通知BaseAdapter刷新
addNewItem(mInCityName.getText().toString());//调用添加页面
mInCityName.setText("");//清除输入框的内容
}
});
}
/**
* @author Administrator
*初始化
*/
private void initView() {
vpager_one = (ViewPager) findViewById(R.id.viewpager);
mCity = new ArrayList<String>();
aList = new ArrayList<View>();
LayoutInflater li = getLayoutInflater();
View view = li.inflate(R.layout.activity_citylist, null);
aList.add(view);
lv = (ListView) view.findViewById(R.id.lv);
mAdd = (Button) view.findViewById(R.id.add);
mInCityName = (EditText) view.findViewById(R.id.incity);
}
/**
* @author Administrator
*添加页面
*/
private void addNewItem(String string) {
LayoutInflater li = getLayoutInflater();
// 引入布局
view1 = li.inflate(R.layout.activity_one, null);
mTextView = (TextView) view1.findViewById(R.id.cityName);
mTextView.setText(string);
aList.add(view1);
// 将view集合船给ViewPageradapter
mAdapter.setListViews(aList);
// 通知ViewPageradapter刷新
mAdapter.notifyDataSetChanged();
}
/**
* @author Administrator
*删除页面
*/
private void removeItem(int position) {
aList.remove(position);
mAdapter.setListViews(aList);
// System.out.println(aList.size());
// 移除所有页面,然后通知adapter刷新
vpager_one.removeAllViews();
mAdapter.notifyDataSetChanged();
}
/**
* @author Administrator
*
*/
public class MyOnPageChangeListener implements OnPageChangeListener {
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
}
}
BaseAdapter适配器程序:
package com.example.viewpager;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private Context mContext;
private List<String> list;
private TextView textView;
private Holder holder;
public MyAdapter(Context context, ArrayList<String> list) {
// TODO Auto-generated constructor stub
mContext = context;
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(null==convertView)
{
holder=new Holder();
convertView=LayoutInflater.from(mContext).inflate(R.layout.activity_city, null); //mContext指的是调用的Activtty
holder.textView=(TextView)convertView.findViewById(R.id.textView);
convertView.setTag(holder);
}
else
{
holder=(Holder)convertView.getTag();
}
holder.textView.setText(list.get(position));
return convertView;
}
static class Holder
{
public TextView textView;
}
}
ViewPagerAdapter:
package com.example.viewpager;
import java.util.ArrayList;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
public class MyPageAdapter extends PagerAdapter {
private ArrayList<View> viewLists;
private int size;
public MyPageAdapter(ArrayList<View> viewLists){
super();
this.viewLists = viewLists ;
}
public void setListViews(ArrayList<View> viewLists) {
this.viewLists = viewLists;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return viewLists.size();
}
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return PagerAdapter.POSITION_NONE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
// TODO Auto-generated method stub
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
if (getCount()>1) {
((ViewPager) container).removeView(viewLists.get(position));
System.out.println("remove"+position);
}
// else {
// / System.out.println("remove1"+position);
// }
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
((ViewPager) container).addView(viewLists.get(position), 0);
return viewLists.get(position);
}
}
代码如上,主要碰到的问题有
1.BaseAdapter的getView方法中,最开始只使用了convertView方法优化,结果在在接收数据显示在Listview上时乱序了,删除过程中也会乱序,通过log打印显示接收正常,最后使用convertView+Hold方法解决了。
2.ViewPager添加过程比较顺利,但是删除的过程遇到各种问题。第一个问题是移除数据后notifyDataSetChanged()无效,于是度娘,网上解决方案都是在ViewPagerAdapter中重写如下方法。
Public int getItemPosition(Object object) {
主要是return POSITION_NONE;具体原因本人还没明白,参考以下链接http://www.xuebuyuan.com/1895454.html。
// TODO Auto-generated method stub
return PagerAdapter.POSITION_NONE;
}
参考网上方案后,删除页面成功了,但第二个问题又出来了,删除后对前一个页面显示内容有影响,最后采用先removeAllViews(),然后notifyDataSetChanged()解决了。第三个问题,当删除到listview中只有一项数据时,再次点击删除时app崩溃了,Logcat显示数组越界错误。重写ViewPagerAdapter中的destroyItem方法如下
public void destroyItem(ViewGroup container, int position, Object object) {
。
// TODO Auto-generated method stub
if (getCount()>1) {
((ViewPager) container).removeView(viewLists.get(position));
System.out.println("remove"+ position);
}
// else {
// System.out.println("remove1"+ position);
// }
}
本人新手一个,以上问题只知道这样可以解决,但是不知道为什么要这样。如果有大神不吝赐教,我将不胜感激!!!