Listview 添加第二项后只显示一项
Listview only display one item after add the second item
为什么我的自定义列表视图只显示通过单击 window 中的 "add" 按钮在 EditText 中键入的最新数据(列表视图中只有一行),右边应该附加在列表视图项的下一行中,将数据保存并读取到 .dat 文件中。任何人都可以帮助我使用下面的代码吗?
这是我的 MainActivity 代码:
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
private EditText edText;
private Button btnAdd;
private DatePickerDialog.OnDateSetListener dpdDateTimePicker;
private TextView tvDate;
private TextView tvListItem;
private TextView tvListDate;
private ArrayList<Items> arrItem;
private ItemListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edText = findViewById(R.id.edText);
btnAdd = findViewById(R.id.btnAdd);
tvDate = findViewById(R.id.tvDate);
tvListItem = findViewById(R.id.tvItem);
tvListDate = findViewById(R.id.tvDate);
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
//Date start
tvDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(MainActivity.this,
android.R.style.Theme_Holo_Dialog_MinWidth,
dpdDateTimePicker,
year, month,day);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
});
dpdDateTimePicker = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
month = month + 1;
String date = dayOfMonth + "/" + month + "/" + year;
tvDate.setText(date);
}
};
//Date end
//Read Data
arrItem = FileHelper.readData(this);
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, arrItem);
lvItemList.setAdapter(adapter);
btnAdd.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnAdd:
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
String itementered = edText.getText().toString();
String dateentered = tvDate.getText().toString();
Items item1 = new Items(itementered, dateentered);
ArrayList<Items> ItemList = new ArrayList<>();
ItemList.add(item1);
FileHelper.writeData(ItemList, this);
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, ItemList);
lvItemList.setAdapter(adapter);
//Clear TextView and EditText
edText.setText("");
tvDate.setText("");
Toast.makeText(this,"Task Added", Toast.LENGTH_SHORT).show();
break;
}
}
}
FileHelper class 将 read/write 项目转化为 .dat
public class FileHelper {
public static final String FILENAME = "ItemList.dat";
public static void writeData(ArrayList<Items> item, Context context){
try {
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(item);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static ArrayList<Items> readData(Context context){
ArrayList<Items> arItemList = null;
try {
FileInputStream fis = context.openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(fis);
arItemList = (ArrayList<Items>) ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return arItemList;
}
}
我的自定义 ItemListAdapter
public class ItemListAdapter extends ArrayAdapter<Items> {
private Context mContext;
int mResource;
public ItemListAdapter(Context context, int resource, ArrayList<Items> objects) {
super(context, resource, objects);
this.mContext = context;
this.mResource = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//get the Item info
String task = getItem(position).getTask();
String date = getItem(position).getDate();
//Create the task object with the information
Items item = new Items(task, date);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
TextView tvDate = (TextView) convertView.findViewById(R.id.tvDate);
TextView tvTask = (TextView) convertView.findViewById(R.id.tvItem);
tvDate.setText(date);
tvTask.setText(task);
return convertView;
}
}
项目class
public class Items implements Serializable {
private String task;
private String date;
public Items(String task, String date) {
this.task = task;
this.date = date;
}
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
在你的 onClick
函数中,你总是创建一个新的 ArrayList<Items> ItemList
并向它添加一个 Items
,然后你创建一个新的 ItemListAdapter
,显示这个lvItemList
.
中的新(单项)列表
代码应该更像下面。
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnAdd:
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
String itementered = edText.getText().toString();
String dateentered = tvDate.getText().toString();
Items item1 = new Items(itementered, dateentered);
//do not create a new ArrayList
//ArrayList<Items> ItemList = new ArrayList<>();
//ItemList.add(item1);
//append item1 to the existing one instead
arrItem.add(item1);
//you might have to change this line to handle addition of single item
//FileHelper.writeData(ItemList, this);
//however after a quick look at FileHelper it seems that
FileHelper.writeData(arrItem, this); //might work
//now you also don't need to/shouldn't create a new adapter
//adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, ItemList);
//lvItemList.setAdapter(adapter);
//just notify that arrItem has changed and the adapter will update the ListView
adapter.notifyDataSetChanged();
//Clear TextView and EditText
edText.setText("");
tvDate.setText("");
Toast.makeText(this,"Task Added", Toast.LENGTH_SHORT).show();
break;
}
}
注意我还包括了 adapter.notifyDataSetChanged()
,因为这确实是适配器方便的原因。
您首先在 onCreate
:
中将 adapter
设置为 lvItemList
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, arrItem);
lvItemList.setAdapter(adapter);
这会在 lvItemList
中显示 arrItem
的内容。如果您稍后希望添加项目,请将其添加到 arrItem
并调用 adapter.notifyDataSetChanged()
以显示更改。
关于 FileHelper
的注释。看起来 FileHelper.writeData()
重写了整个文件,因此写入 arrItem
应该会产生所需的结果,其中 lvItemList
中显示的所有项目也存储在文件中。
为什么我的自定义列表视图只显示通过单击 window 中的 "add" 按钮在 EditText 中键入的最新数据(列表视图中只有一行),右边应该附加在列表视图项的下一行中,将数据保存并读取到 .dat 文件中。任何人都可以帮助我使用下面的代码吗?
这是我的 MainActivity 代码:
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
private EditText edText;
private Button btnAdd;
private DatePickerDialog.OnDateSetListener dpdDateTimePicker;
private TextView tvDate;
private TextView tvListItem;
private TextView tvListDate;
private ArrayList<Items> arrItem;
private ItemListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edText = findViewById(R.id.edText);
btnAdd = findViewById(R.id.btnAdd);
tvDate = findViewById(R.id.tvDate);
tvListItem = findViewById(R.id.tvItem);
tvListDate = findViewById(R.id.tvDate);
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
//Date start
tvDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(MainActivity.this,
android.R.style.Theme_Holo_Dialog_MinWidth,
dpdDateTimePicker,
year, month,day);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialog.show();
}
});
dpdDateTimePicker = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
month = month + 1;
String date = dayOfMonth + "/" + month + "/" + year;
tvDate.setText(date);
}
};
//Date end
//Read Data
arrItem = FileHelper.readData(this);
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, arrItem);
lvItemList.setAdapter(adapter);
btnAdd.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnAdd:
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
String itementered = edText.getText().toString();
String dateentered = tvDate.getText().toString();
Items item1 = new Items(itementered, dateentered);
ArrayList<Items> ItemList = new ArrayList<>();
ItemList.add(item1);
FileHelper.writeData(ItemList, this);
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, ItemList);
lvItemList.setAdapter(adapter);
//Clear TextView and EditText
edText.setText("");
tvDate.setText("");
Toast.makeText(this,"Task Added", Toast.LENGTH_SHORT).show();
break;
}
}
}
FileHelper class 将 read/write 项目转化为 .dat
public class FileHelper {
public static final String FILENAME = "ItemList.dat";
public static void writeData(ArrayList<Items> item, Context context){
try {
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(item);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static ArrayList<Items> readData(Context context){
ArrayList<Items> arItemList = null;
try {
FileInputStream fis = context.openFileInput(FILENAME);
ObjectInputStream ois = new ObjectInputStream(fis);
arItemList = (ArrayList<Items>) ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return arItemList;
}
}
我的自定义 ItemListAdapter
public class ItemListAdapter extends ArrayAdapter<Items> {
private Context mContext;
int mResource;
public ItemListAdapter(Context context, int resource, ArrayList<Items> objects) {
super(context, resource, objects);
this.mContext = context;
this.mResource = resource;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
//get the Item info
String task = getItem(position).getTask();
String date = getItem(position).getDate();
//Create the task object with the information
Items item = new Items(task, date);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
TextView tvDate = (TextView) convertView.findViewById(R.id.tvDate);
TextView tvTask = (TextView) convertView.findViewById(R.id.tvItem);
tvDate.setText(date);
tvTask.setText(task);
return convertView;
}
}
项目class
public class Items implements Serializable {
private String task;
private String date;
public Items(String task, String date) {
this.task = task;
this.date = date;
}
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
在你的 onClick
函数中,你总是创建一个新的 ArrayList<Items> ItemList
并向它添加一个 Items
,然后你创建一个新的 ItemListAdapter
,显示这个lvItemList
.
代码应该更像下面。
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnAdd:
ListView lvItemList = (ListView) findViewById(R.id.lvItem);
String itementered = edText.getText().toString();
String dateentered = tvDate.getText().toString();
Items item1 = new Items(itementered, dateentered);
//do not create a new ArrayList
//ArrayList<Items> ItemList = new ArrayList<>();
//ItemList.add(item1);
//append item1 to the existing one instead
arrItem.add(item1);
//you might have to change this line to handle addition of single item
//FileHelper.writeData(ItemList, this);
//however after a quick look at FileHelper it seems that
FileHelper.writeData(arrItem, this); //might work
//now you also don't need to/shouldn't create a new adapter
//adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, ItemList);
//lvItemList.setAdapter(adapter);
//just notify that arrItem has changed and the adapter will update the ListView
adapter.notifyDataSetChanged();
//Clear TextView and EditText
edText.setText("");
tvDate.setText("");
Toast.makeText(this,"Task Added", Toast.LENGTH_SHORT).show();
break;
}
}
注意我还包括了 adapter.notifyDataSetChanged()
,因为这确实是适配器方便的原因。
您首先在 onCreate
:
adapter
设置为 lvItemList
adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, arrItem);
lvItemList.setAdapter(adapter);
这会在 lvItemList
中显示 arrItem
的内容。如果您稍后希望添加项目,请将其添加到 arrItem
并调用 adapter.notifyDataSetChanged()
以显示更改。
关于 FileHelper
的注释。看起来 FileHelper.writeData()
重写了整个文件,因此写入 arrItem
应该会产生所需的结果,其中 lvItemList
中显示的所有项目也存储在文件中。