无法在列表视图中添加多个项目
Posted
技术标签:
【中文标题】无法在列表视图中添加多个项目【英文标题】:Unable to add more than one item in a listview 【发布时间】:2021-10-03 20:45:54 【问题描述】:我正在开发一个任务应用程序,为此我创建了一个列表视图,其中显示了由任务名称、它们的优先级等组成的列表项。提供给列表视图的数据来自一个 sqlite 数据库。但是,我无法在列表中添加多个项目。我不知道为什么。我已经创建了一种方法来做到这一点,但它似乎不起作用。我不知道错误是由于数据库还是我的方法本身造成的。即使调试也无济于事。请注意,我使用的是列表适配器,因为我使用的是自定义列表视图。
显示列表的活动代码:
package com.example.taskmasterv3;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class TaskSummary extends AppCompatActivity
ListView lvTaskList;
TextView tvBreak, tvBreakAfterEvery, txt1, txt2, text1, hmm;
TextView break_duration_mins;
ArrayList<SubtaskPartTwo> subtaskList = new ArrayList<>();
String subtname;
String pri;
String time;
DBHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_summary);
lvTaskList = findViewById(R.id.lvTaskList);
tvBreak = findViewById(R.id.tvBreak);
tvBreakAfterEvery = findViewById(R.id.tvBreakAfterEvery);
txt1 = findViewById(R.id.txt1);
txt2 = findViewById(R.id.txt2);
break_duration_mins = findViewById(R.id.break_duration_mins);
text1 = findViewById(R.id.text1);
hmm = findViewById(R.id.hmm);
dbHelper = new DBHelper(this);
subtname = getIntent().getStringExtra("subtaskname");
pri = getIntent().getStringExtra("pri");
time = getIntent().getStringExtra("time");
// Using adapter for listview :
SubtaskDetailAdapter adapter = new SubtaskDetailAdapter(this, subtaskList);
lvTaskList.setAdapter(adapter);
SubtaskPartTwo subtaskPartTwo = new SubtaskPartTwo(subtname, pri, time);
subtaskList.add(subtaskPartTwo);
adapter.addANewSubTask(subtaskPartTwo);
double working_hours = getIntent().getIntExtra("working_hours", 1);
double working_minutes = getIntent().getIntExtra("working_minutes", 0);
double without_break_hours = getIntent().getIntExtra("without_break_hours", 1);
double without_break_minutes = getIntent().getIntExtra("without_break_minutes", 0);
double break_duration = getIntent().getIntExtra("break_duration", 20);
String a = working_hours + " h";
txt1.setText(a);
String b = working_minutes + " m";
break_duration_mins.setText(b);
String c = break_duration + " m";
txt2.setText(c);
//Mathematics
double g = working_hours * 100;
double h = g + working_minutes;
double i = h + break_duration;
double j = i / 60;
double p = (int) j;
double q = j - p;
double r = q * 60;
without_break_hours = p;
without_break_minutes = r;
String d = without_break_hours + " h";
String e = without_break_minutes + " m";
text1.setText(d);
hmm.setText(e);
适配器类代码:
package com.example.taskmasterv3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class SubtaskDetailAdapter extends ArrayAdapter<SubtaskPartTwo>
private final Context context;
private ArrayList<SubtaskPartTwo> values;
public boolean deleted;
public SubtaskDetailAdapter(Context context, ArrayList<SubtaskPartTwo> list)
//since your are using custom view,pass zero and inflate the custom view by overriding getview
super(context, 0 , list);
this.context = context;
this.values = list;
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent)
//check if its null, if so inflate it, else simply reuse it
if (convertView == null)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.task_summary_item, parent, false);
//use convertView to refer the childviews to populate it with data
TextView tvSubtaskName = convertView.findViewById(R.id.tvlolitaskname);
ImageView ivPri = convertView.findViewById(R.id.ivloliPri);
ImageView ivTime = convertView.findViewById(R.id.ivloliTime);
tvSubtaskName.setText(values.get(position).getSubtaskName());
if (values.get(position).getPri() == "h")
ivPri.setImageResource(R.drawable.priority_high);
if (values.get(position).getPri() == "m")
ivPri.setImageResource(R.drawable.priority_med);
if (values.get(position).getPri() == "l")
ivPri.setImageResource(R.drawable.priority_low);
if (values.get(position).getTime() == "more")
ivPri.setImageResource(R.drawable.time_symbol_more);
if (values.get(position).getPri() == "med")
ivPri.setImageResource(R.drawable.time_symbol_med);
if (values.get(position).getPri() == "less")
ivPri.setImageResource(R.drawable.time_symbol_less);
//return the view you inflated
return convertView;
//to keep adding the new subtasks try the following
public void addANewSubTask(SubtaskPartTwo newSubTask)
ArrayList<SubtaskPartTwo> newvalues = new ArrayList<>(this.values);
newvalues.add(newSubTask);
this.values = newvalues;
notifyDataSetChanged();
列表视图活动的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent"
android:layout_
android:layout_
android:background="@color/background"
tools:context=".TaskSummary">
<!-- hello -->
<ScrollView
android:id="@+id/scrollView2"
android:layout_
android:layout_
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<LinearLayout
android:id="@+id/okay"
android:layout_
android:layout_
android:layout_margin="16dp"
android:orientation="vertical">
<ListView
android:id="@+id/lvTaskList"
android:layout_
android:layout_
android:layout_margin="16dp">
</ListView>
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<LinearLayout
android:layout_
android:layout_
android:orientation="horizontal">
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/tvBreak"
android:layout_
android:layout_
android:layout_margin="8dp"
android:fontFamily="@font/roboto"
android:text="Total Working Time (Including Breaks)"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/txt1"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_margin="8dp"
android:layout_weight="1"
android:fontFamily="@font/roboto"
android:gravity="right"
android:text="00 h"
android:textColor="#B8AEAE"
android:textSize="20sp" />
<TextView
android:id="@+id/break_duration_mins"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:gravity="left"
android:text="20 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
<!-- hello -->
<!-- hello -->
<LinearLayout
android:layout_
android:layout_
android:layout_margin="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_
android:layout_
android:orientation="horizontal">
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/tvWorktimeWithoutBreak"
android:layout_
android:layout_
android:layout_margin="8dp"
android:fontFamily="@font/roboto"
android:text="Work Time Before Each Break"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/text1"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_margin="8dp"
android:layout_weight="1"
android:fontFamily="@font/roboto"
android:gravity="right"
android:text="00 h"
android:textColor="#B8AEAE"
android:textSize="20sp" />
<TextView
android:id="@+id/hmm"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:gravity="left"
android:text="20 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- hello -->
<LinearLayout
android:layout_
android:layout_
android:orientation="horizontal">
<TextView
android:id="@+id/tvBreakAfterEvery"
android:layout_
android:layout_
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:fontFamily="@font/roboto"
android:text="Break Duration"
android:textColor="#B8AEAE"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="@+id/lvTaskList"
app:layout_constraintEnd_toStartOf="@+id/lvTaskList"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txt2"
android:layout_
android:layout_
android:layout_margin="8dp"
android:fontFamily="@font/roboto"
android:gravity="center_horizontal"
android:text="30 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<Button
android:id="@+id/btnStart"
android:layout_
android:layout_
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="16dp"
android:text="Start" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
编辑:数据库代码
package com.example.taskmasterv3;
public class TaskInfo extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_info);
tvTaskName = findViewById(R.id.tvTaskName);
btnProceed = findViewById(R.id.btnProceed);
dbHelper = new DBHelper(this);
tvTaskName.setVisibility(View.INVISIBLE);
if (tvTaskName.getText().equals(""))
tvTaskName.setClickable(false);
else
tvTaskName.setClickable(true);
btnSaveTaskName.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
tvTaskName.setVisibility(View.VISIBLE);
tvTaskName.setText(etTaskName.getText().toString().toUpperCase().trim());
etTaskName.setVisibility(View.GONE);
btnSaveTaskName.setVisibility(View.GONE);
btnNewSubtask.setEnabled(true);
);
tvTaskName.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String tasksname = tvTaskName.getText().toString().trim();
tvTaskName.setText("");
etTaskName.setVisibility(View.VISIBLE);
etTaskName.setText(tasksname);
btnSaveTaskName.setVisibility(View.VISIBLE);
);
btnNewSubtask.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent i2 = new Intent(TaskInfo.this, SubtaskActivity.class);
startActivityForResult(i2, ENTER_SUBTASK);
overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);
);
// THE DATABASE PART
btnProceed.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Cursor res = dbHelper.getdata();
while(res != null && res.moveToNext())
subtname = res.getString(0);
pri = res.getString(1);
time = res.getString(2);
if (etWorkingHours.getText().toString().isEmpty())
etWorkingHours.setText("0");
if (etWorkingMinutes.getText().toString().isEmpty())
etWorkingMinutes.setText("0");
if (etWorkinghrs.getText().toString().isEmpty())
etWorkinghrs.setText("0");
if (etWorkingMins.getText().toString().isEmpty())
etWorkingMins.setText("0");
int working_hours = Integer.parseInt(etWorkinghrs.getText().toString().trim());
int working_minutes = Integer.parseInt(etWorkingMins.getText().toString().trim());
int without_break_hours = Integer.parseInt(etWorkingHours.getText().toString().trim());
int without_break_minutes = Integer.parseInt(etWorkingMinutes.getText().toString().trim());
if (etWorkingHours.getText().toString().isEmpty() || etWorkingMinutes.getText().toString().isEmpty() || etWorkinghrs.getText().toString().isEmpty() || etWorkingMins.getText().toString().isEmpty())
Toast.makeText(TaskInfo.this, "Field cannot be empty, please try again.", Toast.LENGTH_SHORT).show();
else
if (working_hours != 0)
if (working_hours > without_break_hours)
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("priigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
startActivity(intent);
if (working_hours == without_break_hours)
if (working_minutes >= without_break_minutes)
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("priigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
intent.putExtra("subtaskname", subtname);
intent.putExtra("pri", pri);
intent.putExtra("time", time);
startActivity(intent);
if (working_minutes < without_break_minutes)
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
if (working_hours < without_break_hours)
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
if (working_hours == 0)
if (without_break_hours == 0)
if (working_minutes >= without_break_minutes)
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("prihigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
startActivity(intent);
if (working_minutes < without_break_minutes)
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
if (without_break_hours != 0)
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
);
boolean delete = getIntent().getBooleanExtra("deleted", false);
if (delete)
【问题讨论】:
用户 NestedScrollView 使用列表或 recyclerview 而不是 ScrollView,还要确保您的 listview xml 文件的父视图为 wrap_content 而不是 match_parent,这些都是初学者的常见问题 【参考方案1】:问题是您正在创建一个新的ArrayList
,而适配器则使用旧的。这就是为什么notifyDataSetChanged()
不起作用的原因,因为适配器的支持列表没有改变。
要解决此问题,请直接更新 values
列表
public void addANewSubTask(SubtaskPartTwo newSubTask)
this.values.add(newSubTask);
notifyDataSetChanged();
或者,add()
通过适配器本身。
public void addANewSubTask(SubtaskPartTwo newSubTask)
add(newSubTask);
notifyDataSetChanged();
即使我添加一项,它也会显示 2(都相同)
您似乎添加了两次新元素:
SubtaskPartTwo subtaskPartTwo = new SubtaskPartTwo(subtname, pri, time);
subtaskList.add(subtaskPartTwo);
adapter.addANewSubTask(subtaskPartTwo);
只需通过适配器添加,因为它也会通知。检查其他地方是否有此类重复项。
【讨论】:
有改进。不过,您的输入正在做一些奇怪的事情......例如,如果我添加 2 个项目,它会添加 2 个项目,但是这两个项目都是第一个项目的重复项。此外,在 2 之后没有添加任何项目;编辑:即使我添加一项,它也会显示 2(都相同) 我看到并实施了您的更新,我们又回到了第一格,哈哈。只能将一项添加到列表中...但是让我也添加数据库的代码,可能是我的 sqlite 数据库导致了问题..请检查我在我的问题中的编辑 @Aadhitya 添加重复项或停止添加项目时,您是否在控制台上收到任何错误?以上是关于无法在列表视图中添加多个项目的主要内容,如果未能解决你的问题,请参考以下文章
将多个项目添加到列表视图,每个项目从按钮单击的另一个意图接收