无法在列表视图中添加多个项目

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 添加重复项或停止添加项目时,您是否在控制台上收到任何错误?

以上是关于无法在列表视图中添加多个项目的主要内容,如果未能解决你的问题,请参考以下文章

如何从列表视图按钮单击将多个数据添加到数组列表?

将多个项目添加到列表视图,每个项目从按钮单击的另一个意图接收

OnItemClick 在列表视图中无法正常工作

当检查可以是字符串数组中的一个或多个项目时,如何将列表视图项目添加到数组中?

无法将多个项目插入列表视图控件的单行

反应本机列表视图添加项目不起作用