Listview仅在添加第二个项目后显示一个项目

时间:2019-11-02 13:14:26

标签: android listview arraylist custom-adapter

为什么我的自定义列表视图仅显示通过单击该窗口中的“添加”按钮在EditText中键入的最新数据(列表视图中仅一行),因此应将其附加在列表视图项的下一行中,并且保存并将数据读取到.dat文件中。有人可以在下面提供我的代码帮助我吗?

这是我的MainActivity代码:

#include <iostream>
#include <conio.h>
using namespace std;
bool gameOver;
const int width = 20;
const int height = 20;
int x, y, fruitX, fruitY;
enum eDirecton { STOP = 0, LEFT, RIGHT, UP, DOWN };
eDirecton dir;

void Setup() {
    gameOver = false;
    dir = STOP;
    x = width / 2;
    y = height / 2;
    fruitX = rand() % width;
    fruitY = rand() % height;
}

void Draw() {
    system("cls");
    for(int i = 0; i < width + 2; i++) cout << "#";
    cout << endl;

    for(int i = 0; i < height; i++) {
        for(int j = 0; j < width; j++) {
            if(j == 0) cout << "#";
            if(i == y && j == x)
                cout << "O";
            else if(i == fruitY && j == fruitX)
                cout << "F";
            else
                cout << " ";

            if(j == width - 1) cout << "#";
        }
        cout << endl;
    }

    for(int i = 0; i < width + 2; i++) cout << "#";
    cout << endl;
}

void Input() {
    if(_kbhit()) {
        switch(_getch()) {
        case 'a':
            dir = LEFT;
            break;
        case 'd':
            dir = RIGHT;
            break;
        case 'w':
            dir = UP;
            break;
        case 's':
            dir = DOWN;
            break;
        case 'q':
            gameOver = true;
            break;
        }
    }
}

void Logic() {
    switch(dir) {
    case LEFT:
        x--;
        break;
    case RIGHT:
        x++;
        break;
    case UP:
        y++;
        break;
    case DOWN:
        y--;
        break;
    default:
        break;
    }
}

int main() {
    Setup();
    while(!gameOver) {
        Draw();
        Input();
        Logic();
        // sleep (10)
    }

    return 0;
}

FileHelper类,用于将项目读/写到.dat

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;

    }
}
}

我的自定义ItemListAdapter

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;
}
}

物品类

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;

}
}

1 个答案:

答案 0 :(得分:0)

在您的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(),因为这确实是适配器方便的原因。 您首先在adapter中将lvItemList设置为onCreate

adapter = new ItemListAdapter(this, R.layout.adapter_view_layout, arrItem);
lvItemList.setAdapter(adapter);

这将显示arrItemlvItemList的内容。如果以后要添加项目,请将其添加到arrItem并调用adapter.notifyDataSetChanged()以显示更改。

关于FileHelper的注释。看来FileHelper.writeData()会重写整个文件,因此写入arrItem应该会产生所需的结果,其中lvItemList中显示的所有项目也都存储在文件中。