Android - 从自定义列表视图中删除一个项目并在长按时更新它

Posted

技术标签:

【中文标题】Android - 从自定义列表视图中删除一个项目并在长按时更新它【英文标题】:Android - Delete an item from Custom Listview and update it when long clicked 【发布时间】:2021-03-05 20:01:09 【问题描述】:

在我的应用程序中,我使用的是自定义 Listview,当长按 Listview 时,我需要同时从 Listview 中删除一个项目以及 CSV 文件中的相应行。

我的 CSV 文件如下所示

2020/11/22,10:30PM,96.3°F,正常,身体

2020/11/22,10:30PM,98.2°F,正常,身体

2020/11/22,10:31PM,96.7°F,正常,身体

2020/11/22,10:40PM,95.0°F,正常,身体

例如,如果 Listview 中的第二项在长按时被删除,则在长按 Listview 时,上方 CSV 文件中的第二行对应的 CSV 文件中的数据行也应该被删除。强>

这是我的代码:

LogViewActivity.java

public class LogViewActivity extends BaseAppCompatActivity 

    private static final String TAG = "LogViewActivity";

    private File logFile;
    private Toolbar toolbar;
    private ListView lvproducts;
    ArrayList<Product> list;
    ProductAdapter adapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        setContentView(R.layout.log_view_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) 
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() 
                @Override
                public void onClick(View view) 
                    finish();
                
            );
        



    

    public void onResume() 
        super.onResume();


        logFile = (File) getIntent().getExtras().get(Constants.EXTRA_LOG_FILE);
        if (logFile != null) 
            toolbar.setTitle(logFile.getName());
            try 
                setLogText(logFile);
             catch (FileNotFoundException e) 
                e.printStackTrace();
            
        
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        getMenuInflater().inflate(R.menu.menu_log_view, menu);
        return true;
    

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        Intent intent;
        switch (item.getItemId()) 
            case R.id.action_send_to:
                intent = new Intent();
                intent.setAction(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(logFile), "text/plain");
                startActivity(intent);
                break;
            default:
                Log.e(TAG, "Unknown id");
                break;
        
        return super.onOptionsItemSelected(item);
    

    private void setLogText(File file) throws FileNotFoundException 

    // Textview visisbility is invisible and used only for setting up String data.

        TextView textView1 = (TextView) findViewById(R.id.tvview1);
        TextView textView2 = (TextView) findViewById(R.id.tvview2);
        TextView textView3 = (TextView) findViewById(R.id.tvview3);
        TextView textView4 = (TextView) findViewById(R.id.tvview4);
        TextView textView5 = (TextView) findViewById(R.id.tvview5);


        lvproducts = (ListView) findViewById(R.id.lvproducts);

        list =new ArrayList<Product>();


        Scanner inputStream;

        inputStream = new Scanner(file);

        while(inputStream.hasNext())
            String line= inputStream.next();

            if (line.equals(""))  continue;  // <--- notice this line

            String[] values = line.split(",");
            String V = values[0];
            String W= values[1];
            String X= values[2];
            String Y= values[3];
            String Z= values[4];

            // Textview visisbility is invisible and used only for setting up String data.

            textView1.setText(Z);
            textView2.setText(X);
            textView3.setText(Y);
            textView4.setText(V);
            textView5.setText(W);

            Product product1 = new Product(textView1.getText().toString(), textView2.getText().toString(), textView3.getText().toString(), textView4.getText().toString(), textView5.getText().toString());

            list.add(product1);


            adapter = new ProductAdapter(LogViewActivity.this, list);
            lvproducts.setAdapter(adapter);
        
        inputStream.close();

         lvproducts.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() 
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) 

            int which_item = position;

            new AlertDialog.Builder(LogViewActivity.this)
                    .setTitle(getResources().getString(R.string.delete_log_file_title))
                    .setMessage(getResources().getString(R.string.delete_log_file_text) + "\n"
                            + getResources().getString(R.string.file_name))
                    .setPositiveButton(android.R.string.ok,
                            new DialogInterface.OnClickListener() 
                                public void onClick(DialogInterface dialog, int which) 
                                    list.remove(which_item);
                                    adapter.notifyDataSetChanged();

                                
                            )
                    .setNegativeButton(android.R.string.cancel, null)
                    .show();
            return true;
        
    );



    


Product.java

public class Product 

    private String mode;
    private String temp;
    private String condition;
    private String dates;
    private String times;

    public Product(String mode, String temp, String condition, String dates, String times) 
        this.mode = mode;
        this.temp = temp;
        this.condition = condition;
        this.dates = dates;
        this.times = times;
    

    public String getMode() 
        return mode;
    

    public String getTemp() 
        return temp;
    

    public String getCondition() 
        return condition;
    

    public String getDates() 
        return dates;
    

    public String getTimes() 
        return times;
    

ProductAdapter.java

public class ProductAdapter extends ArrayAdapter<Product> 

    private final Context context;
    private final ArrayList<Product> values;

    public ProductAdapter(@NonNull Context context, ArrayList<Product> list) 
        super(context, R.layout.row_layout, list);
        this.context = context;
        this.values = list;
    

    @SuppressLint("ResourceAsColor")
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) 

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowview = inflater.inflate(R.layout.row_layout, parent, false);

        CardView cdview = (CardView) rowview.findViewById(R.id.cdview);


        TextView tvtemp = (TextView) rowview.findViewById(R.id.tvtemp);
        TextView tvcondition = (TextView) rowview.findViewById(R.id.tvcondition);
        TextView tvdate = (TextView) rowview.findViewById(R.id.tvdate);
        TextView tvtime = (TextView) rowview.findViewById(R.id.tvtime);

        ImageView ivmode = (ImageView) rowview.findViewById(R.id.ivmode);

        tvtemp.setText(values.get(position).getTemp());
        tvcondition.setText(values.get(position).getCondition());
        tvdate.setText(values.get(position).getDates());
        tvtime.setText(values.get(position).getTimes());


        if(values.get(position).getMode().equals("Object") && (values.get(position).getCondition().equals("None")) && (!values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.back_blue);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.homewhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("Normal")) && (!values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.backgreen);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("Low-Grade-Fever")) && (!values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.backyellow);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("High-Fever")) && (!values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.backred);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("None")) && (values.get(position).getTemp().equals("HIGH")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.backred);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("None")) && (values.get(position).getTemp().equals("LOW")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.back_low);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Body") && (values.get(position).getCondition().equals("None")) && (values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.back_black);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.headwhite);
        

        else if(values.get(position).getMode().equals("Object") && (values.get(position).getCondition().equals("None")) && (values.get(position).getTemp().equals("No-Data")))
        
            Drawable draw8 = cdview.getResources().getDrawable(R.drawable.back_black);
            cdview.setBackground(draw8);
            ivmode.setImageResource(R.drawable.homewhite);
        

           return rowview;
    

请帮帮我。谢谢!

【问题讨论】:

嗨维涅什。欢迎来到 Stack Overflow,我希望你一切都好。我在包含的代码中没有看到 OnItemLongClickListener。亲切的问候。 嗨,Elletlar。是的,我知道。最初我尝试使用 OnItemLongClickListener,只有项目正在删除,当我再次打开应用程序时,该项目仍然存在,因为它再次从 CSV 文件中读取数据。因此,我需要从我在问题中提到的 CSV 文件中永久删除与该项目相对应的项目和整行。这样当我再次打开应用程序时,它会从 CSV 文件中读取更新后的列表并显示在 Listview 中。 现在,我已将 OnItemLongClickListener 添加到我最初尝试过的代码中。 【参考方案1】:

您只是从加载的数据集中删除项目,因此只有列表项目正在删除。您需要在删除列表项时更新 csv 文件

 lvproducts.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() 
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) 

            int which_item = position;

            new AlertDialog.Builder(LogViewActivity.this)
                    .setTitle(getResources().getString(R.string.delete_log_file_title))
                    .setMessage(getResources().getString(R.string.delete_log_file_text) + "\n"
                            + getResources().getString(R.string.file_name))
                    .setPositiveButton(android.R.string.ok,
                            new DialogInterface.OnClickListener() 
                                public void onClick(DialogInterface dialog, int which) 
                                    list.remove(which_item);
                                    adapter.notifyDataSetChanged();
                                    updateCSVFile();

                                
                            )
                    .setNegativeButton(android.R.string.cancel, null)
                    .show();
            return true;
        
    );

public void updateCSVFile() 
// Write your logic her to update CSV file after item removal.

【讨论】:

感谢您的回复。是的,只有我遇到的问题就像我上面提到的 CSV 数据,当我删除项目(例如 Listview 中的第 2 个项目)时,CSV 文件中相应的第 2 行应该同时删除,当 Listview 长按时,所以该 CSV 文件已更新,当 App 再次打开时,Listview 将显示更新的列表。如何编写此逻辑来更新 CSV 文件? 请帮帮我!! 您的 CSV 文件位于何处?你在使用本地数据库吗? 我的 CSV 文件存储在内部存储中。我没有使用本地数据库,只是将数据写入文件并保存在内部存储(CSV 数据)中。 你需要覆盖这个文件,看看csv编辑库

以上是关于Android - 从自定义列表视图中删除一个项目并在长按时更新它的主要内容,如果未能解决你的问题,请参考以下文章

使用 sqliteDatabase 从自定义列表视图中删除项目

使用sqliteDatabase从自定义列表视图中删除项目

使用微调器从自定义列表视图中删除了错误的行

使用基本适配器解决方案从自定义列表中删除行视图

如何从自定义列表视图中获取选定项目并在 toast 消息中打印?

如何从自定义基础适配器中删除项目?