【问题标题】:Android - How do you pass textview values from Activity-A to an adapterAndroid - 如何将文本视图值从 Activity-A 传递到适配器
【发布时间】:2018-03-14 07:50:28
【问题描述】:

我正在开发一个购物车应用程序,我需要一些关于适配器的帮助。我试图回答一个类似的问题here,但这与我的情况有点不同。我有 3 个课程:MakeSale.java、DetailsActivity.java 和 ShoppingCartListAdapter.java。所以,这是流程。

在MakeSale.java 中,我声明了两个数组列表,第一个是cartItemArrayList 商店要由客户购买的商品。它们是生产者名称、产品名称、数量、unitCost 和第二个,cartCostItemsList 保存购物车中物品的总成本。

内部MakeSale.java

public static List<CartItem> cartItemArrayList = new ArrayList<>();
public static List<Double> cartCostItemsList = new ArrayList<>();

然后我有一个扩展ArrayAdapter 的适配器类。此类链接到一个 XML,list_item,它显示在列表视图上。现在,这个list_item 只显示生产者名称、产品名称、总数量、添加到购物车的每件商品的总成本。当用户想要对列表视图中的项目进行更改(增加或减少要购买的项目数量)时,list_item 已变为可点击。

内部ShoppingCartListAdapter.java

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.zynle.fisp_dealer.Dashboard;
import com.zynle.fisp_dealer.DetailsActivity;
import com.zynle.fisp_dealer.MakeSale;
import com.zynle.fisp_dealer.R;

import java.util.List;
import entities.CartItem;


public class ShoppingCartListAdapter extends ArrayAdapter<CartItem> {

private Context context;
private List<CartItem> cartItems;

public ShoppingCartListAdapter(Context context, List<CartItem> cartItems) {
    super(context, R.layout.list_item, cartItems);
    this.context = context;
    this.cartItems = cartItems;

}

public int getCount() {
    return cartItems.size();
}

public CartItem getItem(int position) {
    return cartItems.get(position);
}

public long getItemId(int position) {
    return cartItems.get(position).getId();
}


@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    LayoutInflater layoutInflater = (LayoutInflater) context.
            getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    final CartItem currentProduct = getItem(position);

    View view = layoutInflater.inflate(R.layout.list_item, parent, false);

    TextView productName_txtv = (TextView) view.findViewById(R.id.nameTextView);
    TextView producerName_txtv = (TextView) view.findViewById(R.id.producerTextView);
    TextView productQuantity_txtv = (TextView) view.findViewById(R.id.qtyTextView);
    TextView productCost_txtv = (TextView) view.findViewById(R.id.priceTextView);

    productName_txtv.setText(cartItems.get(position).getProduct_txt());
    producerName_txtv.setText(cartItems.get(position).getProducer_txt());
    productQuantity_txtv.setText(String.valueOf(cartItems.get(position).getQuantity()));
    productCost_txtv.setText(String.valueOf(cartItems.get(position).getCost_txt()));

    productName_txtv.setText(currentProduct.getProduct_txt());

    int perItem = currentProduct.getCost_txt();
    int quantitee = currentProduct.getQuantity();

    final int total = perItem * quantitee;

    productCost_txtv.setText("Total: K" + total);
    productQuantity_txtv.setText(currentProduct.getQuantity() + " Selected");

    view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent detailsIntent = new Intent(context, DetailsActivity.class);
            detailsIntent.putExtra("name", currentProduct.getProduct_txt());
            detailsIntent.putExtra("quantity", currentProduct.getQuantity());
            detailsIntent.putExtra("total", total);
            context.startActivity(detailsIntent);
        }
    });

    return view;
}


public void makeNewSale() {
    if (getCount() == 0) {

        AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.Theme_AppCompat_Light_Dialog_Alert);
        builder.setTitle(R.string.app_name);
        builder.setIcon(R.mipmap.ic_launcher);
        builder.setMessage("Cart is Empty!")
                .setCancelable(false)
                .setPositiveButton("Add new items", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {

                        Intent intent = new Intent(getContext(), MakeSale.class);
                        getContext().startActivity(intent);

                    }
                })
                .setNegativeButton("Exit", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        Intent intent = new Intent(getContext(), Dashboard.class);
                        getContext().startActivity(intent);
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    }
}

}

从意图来看,我的代码在一个名为DetailsActivity.java 的类中处理有关增加和减少按钮点击量的所有逻辑。当然DetailsActivity.java 链接到一些xml文件。

内部DetailsActivity.java

import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import database.FISP_SQLiteDB;
import entities.CartItem;
import entities.Products;

public class DetailsActivity extends AppCompatActivity {

ImageView imageView;
TextView nameTextView, priceTextView, qtyTextView, available;
Button increaseQtyButton, decreaseQtyButton, contactSupplierButton, deleteButton, confirmButton;

private List<CartItem> cartItems;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    // Get any data passed in from Fragment
    Intent detailsIntent = getIntent();
    final String name = detailsIntent.getStringExtra("name");

    imageView = (ImageView) findViewById(R.id.imageView);
    nameTextView = (TextView) findViewById(R.id.nameTextView);
    available = (TextView) findViewById(R.id.availableQTY);
    priceTextView = (TextView) findViewById(R.id.priceTextView);
    qtyTextView = (TextView) findViewById(R.id.qtyText);
    increaseQtyButton = (Button) findViewById(R.id.increaseQtyButton);
    decreaseQtyButton = (Button) findViewById(R.id.decreaseQtyButton);
    contactSupplierButton = (Button) findViewById(R.id.contactSupplierButton);
    deleteButton = (Button) findViewById(R.id.deleteProductButton);
    confirmButton = (Button) findViewById(R.id.confirm);

    nameTextView.setText(name);

    int quantityPicker = Integer.parseInt(MakeSale.quantityPicker_Npkr.getText().toString());
    qtyTextView.setText("" + quantityPicker);

    final FISP_SQLiteDB db = new FISP_SQLiteDB(DetailsActivity.this);
    final Products product = db.getProduct(name);

    if (product != null) {

        final double productPrice = (product.getPrice() * quantityPicker);
        final int subQuantity = (product.getQuantity() - quantityPicker);

        priceTextView.setText("K" + productPrice);
        available.setText("Available Quantity is " + subQuantity);

        final int[] counter = {quantityPicker};
        final int[] counter1 = {quantityPicker};
        final int[] minteger = {1};

        increaseQtyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                qtyTextView.setText(String.valueOf(counter[0]++));
                int reducingQty = (subQuantity - counter1[0]++);
                double totalingPrice = productPrice + (product.getPrice()* minteger[0]++);
                available.setText(String.valueOf("Available Quantity is " + reducingQty));
                priceTextView.setText("K" + totalingPrice);

                decreaseQtyButton.setEnabled(true);

                if(reducingQty==0){
                    increaseQtyButton.setEnabled(false);
                    decreaseQtyButton.setEnabled(true);

                }
            }
        });

        decreaseQtyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                qtyTextView.setText(String.valueOf(counter[0]--));
                int increasingQty = (subQuantity - counter1[0]--);
                double totalingPrice = productPrice - (product.getPrice()* minteger[0]--);
                available.setText(String.valueOf("Available Quantity is " + increasingQty));
                priceTextView.setText("K" + totalingPrice);

                increaseQtyButton.setEnabled(true);

                if (increasingQty==product.getQuantity()){
                    increaseQtyButton.setEnabled(true);
                    decreaseQtyButton.setEnabled(false);

                }
            }
        });

        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_POSITIVE:

                                //db.deleteProduct(name);
                                finish();
                                break;

                            case DialogInterface.BUTTON_NEGATIVE:
                                break;
                        }
                    }
                };
                AlertDialog.Builder ab = new AlertDialog.Builder(DetailsActivity.this, R.style.MyDialogTheme);
                ab.setMessage("Delete " + name + " ?").setPositiveButton("DELETE", dialogClickListener)
                        .setNegativeButton("CANCEL", dialogClickListener).show();
            }
        });


        contactSupplierButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // TODO Auto-generated method stub
                // Creating alert Dialog with two Buttons
                AlertDialog.Builder alertDialog = new AlertDialog.Builder(DetailsActivity.this, R.style.MyDialogTheme);
                // Setting Dialog Title
                alertDialog.setTitle("Do you want to call?");
                // Setting Dialog Message
                alertDialog.setMessage("" + product.getSupplierName());
                // Setting Icon to Dialog
                //alertDialog.setIcon(R.drawable.warning);
                // Setting Negative "NO" Button
                alertDialog.setNegativeButton("No",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                // Write your code here to execute after dialog
                                dialog.cancel();
                            }
                        });
                // Setting Positive "Yes" Button
                alertDialog.setPositiveButton("Yes",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                                int which) {
                                // Write your code here to execute after dialog
                                Intent callIntent = new Intent(Intent.ACTION_CALL);
                                //callIntent.setData(Uri.parse("" + product.getSupplierPhone().trim()));
                                callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                callIntent.setData(Uri.parse("tel:" + product.getSupplierPhone()));

                                if (ActivityCompat.checkSelfPermission(DetailsActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                                    return;
                                }
                                DetailsActivity.this.startActivity(callIntent);
                            }
                        });

                // Showing Alert Message
                alertDialog.show();
            }
        });

        confirmButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //CartItem cartItem = new CartItem(producer, product, quantity, unitCost);
                //cartItemArrayList.add(cartItem);

                Intent intent = new Intent(DetailsActivity.this, ShoppingCart.class);
                startActivity(intent);
            }
        });
    }
  }
}

现在,当用户单击confirmChangesBtn 时,如何将这些新值(新数量、新总成本)设置/替换到列表视图上的list_item 中?通过这样做更改数组列表中的产品详细信息(cartItemArrayList 和 cartCostItemsList)。将 DetailsActivity.java 中的 textview 值传递给适配器进行显示?我该怎么办?任何人?

【问题讨论】:

  • 只需将值传递给适配器构造函数并创建逻辑!
  • 像在 DetailsActivity 中可能在您的减少/增加按钮单击侦听器中,只需将适配器中使用的列表访问到您的活动 List 在适配器类中创建一个方法 public List getDataList( ) { return cartItems ;// 您在适配器的主要数据列表。现在在活动中调用 List carttemsList = adapter.getDataList();然后 CartItems cartItems = cartItemsList.get(position); // 将受到影响的视图位置。 cartItems.setValue("YourValue"); cartItemsList.add(cartItems, 位置); adapter.notifyDataSetChanged();
  • 您可以使用界面来更改。
  • 您在哪里使用 ShoppingCartListAdapter ?显示活动代码
  • @phpdroid 谢谢,让我看看你的回答太直接了

标签: java android listview arraylist android-adapter


【解决方案1】:

我还将在我的代码中包含 Upendra shah 的解决方案。

在编写解决方案之前,我假设您有两个活动,1. ShoppingCart.java(Holds the listview) & DetailsActivity.java。

请按照步骤一一进行。

第 1 步。 首先从适配器中删除点击侦听器并在适配器中创建一个新方法,该方法将返回您的数据列表。还要在 ShoppingCart Activity 中创建一个全局整数变量,用于保存点击位置;

子步骤 1.A 在 ShoppingCart Activity 中创建如下全局变量

// This will be updated when user clicks on any item of listview.
int clickedPosition = -1;

子步骤 1.B 创建正确的列表视图点击监听器。

view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent detailsIntent = new Intent(context, DetailsActivity.class);
            detailsIntent.putExtra("name", currentProduct.getProduct_txt());
            detailsIntent.putExtra("quantity", currentProduct.getQuantity());
            detailsIntent.putExtra("total", total);
            context.startActivity(detailsIntent);
        }
    });

删除此代码,然后转到 ShoppingCart 活动(您的 listview 对象所在的位置)。那里写下面提到的代码。

yourListView.setOnItemClickListener( new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // updating clicked position variable on list item click.
            clickedPosition = position; 
            Intent detailsIntent = new Intent(ShopingCart.this, DetailsActivity.class);
            detailsIntent.putExtra("name", currentProduct.getProduct_txt());
            detailsIntent.putExtra("quantity", currentProduct.getQuantity());
            detailsIntent.putExtra("total", total);
            startActivityForResult(detailsIntent);
        }
    });

现在为将返回您的适配器数据列表的方法编写代码。

public List<CartItems> getCartItemsFromAdapter() {
      return cartItems;
}

第 2 步。 在购物车活动中,覆盖 onActivityResult

    @Override  
           protected void onActivityResult(int requestCode, int resultCode, Intent data)  
           {  
               super.onActivityResult(requestCode, resultCode, data);  
               if(requestCode == 121)  
                  {  
                    // Update the values according to you, I am using sample key-value.
                    String updatedCost = data.getStringExtra("updatedCost");   
                    List<CartItems> cartItems = adapter.getCartItemsFromAdapter();
                    CartItems cartItemObj = cartItems.get(clickedPosition);
                    cartItemObj.setTotalCost(updatedCost);
                    adapter.notifyDataSetChanged(); // Calling this method will quickly reflect your changes to listView.
                  }  
         }  

第 3 步。 最后,在您的 DetailsActivity 确认按钮或您想要反映这些更改的任何单击按钮处,编写下面提到的代码。

confirmBtn.setOnClickListener(new OnclickListener{

Intent intent = new Intent();  
intent.putExtra("updatedCost", totalCostValue);  
setResult(121, intent);
finish();

});

【讨论】:

  • 非常感谢@Priyavrat,您对ShoppingCart.java 的猜测是正确的,除了我遇到了一些错误。在子步骤 1.B 中,startActivityForResult(detailsIntent); 出现错误,Cannot resolve method startActivityForResult(android.content.Intent) 表示。尝试更改我的 ShoppingCart.java 类以扩展 Activity 但没有任何变化。
  • 然后在第 2 步中,Intent data 出现错误。说Cannot resolve symbol 'data'。我的 onActivityResult、requestCode 和 resultCode 变量从未使用过。然后ShoppingCartListAdapter.notifyDataSetChanged(); 上的另一个错误。错误显示Non-static method 'notifyDataSetChanged()' cannot be referenced from a static context。也许与我在代码中使用 Java 关键字 final 的方式有关?
  • 1.对于子步骤 1.B,确保 ShoppingCart.java 是一个活动,并且您为 lisitview 定义了 itemClick 侦听器(如答案中所述)。 2. 在第 2 步中确保您的 onActivityResult() 方法在 ShoppingCart.java 3. 不要将 notifyDataSetChanged() 视为静态方法。它是适配器类的预定义方法。调用类似 adapterObj.notifyDataSetChanged();通过使用这些步骤,您将完成。告诉我谢谢。
  • 对startActivityForResult(detailsIntent); 仍然是负面的。到目前为止,你告诉我的一切都奏效了。 ShoppingCart.java 在那里并在清单中定义。 itemClick 监听器已按照您在上面的答案中建议的方式完成。但由于某种原因,我的startActivityForResult(detailsIntent); 仍然报错。显然,我错过了什么
  • 您确定 ShoppingCart.java(your class) 是一项活动吗?如果它不是一个活动,那么你需要像这样调用 context.startActivityForResult() 。仍然有问题,然后让我知道代码或我该如何帮助您。谢谢。
【解决方案2】:

当用户从详细信息页面更改购物车值并再次以新值显示在适配器中时,您希望更改适配器数据,您应该在 Resume 方法中初始化适配器视图并通知适配器视图,它可以帮助您重新创建视图具有新的价值。

@Override
    public void onResume() {
        super.onResume();
        if(arrayList.size()>0) {
            myShoppingCartAdapter.notifyDataSetChanged();
            getAllShoppingCartDetails();
        }

    }

【讨论】:

  • 应该在哪个类中初始化适配器视图,Resume方法应该放在哪里?
  • @mayank garg 这不是每次更新/刷新 onResume() 中的列表的最佳选择; onResume 可能会因多种原因被解雇,一个是喜欢,再次锁定和解锁手机。在这种情况下,onResume() 将被触发,并且列表数据将被不必要地更新。
【解决方案3】:

我参考你的代码而不是我建议在适配器中使用startActivityForResult 而不是startActivity。

 view.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent detailsIntent = new Intent(context, DetailsActivity.class);
            detailsIntent.putExtra("name", currentProduct.getProduct_txt());
            detailsIntent.putExtra("quantity", currentProduct.getQuantity());
            detailsIntent.putExtra("total", total);
            context.startActivityForResult(detailsIntent, 121);
        }
    });

比当你增加和减少数量时比将更新的数据添加到意图和setResult()

Intent intent = new Intent();  
intent.putExtra("MESSAGE",message);  
setResult(121,intent);
finish();

比在你的活动中处理你的结果

@Override  
       protected void onActivityResult(int requestCode, int resultCode, Intent data)  
       {  
           super.onActivityResult(requestCode, resultCode, data);  
           // check if the request code is same as what is passed  here it is 2  
           if(requestCode==121)  
              {  
                String message=data.getStringExtra("MESSAGE");   
                //Do you logic like update ui, list, price 
              }  
     }  

【讨论】:

  • 我在调用哪个类的onActivityResult 方法??你刚才说我在我的活动中处理结果
  • 从 DetailsActivity 得到结果后你想要什么??
  • 当用户从详细信息页面更改购物车值时,我想更改适配器数据。然后在列表视图中显示新值
  • 好的,比onActivityResult更新列表数据已经改变,然后通知适配器关于数据集的改变使用adapter.notifydatasetchanged()
【解决方案4】:

@Yokonia Tembo,

在increaseQtyButton.setOnClickListener() 一侧的DetailsActivity.java 代码中,我没有找到MakeSales.java 类的cartItemArrayList 的更改过程

我认为适配器的notifyDataSetChanged() 之前的那些数组列表中的更改将更新您的 CartList 中的值。

除此之外还有其他建议, 如果您正在为 ShoppingCart 应用程序工作,您应该为购物车项目创建一个数据库表,而不是 ArrayList 您将受益于下面提到的几件事

  • DB 表实现即使在终止并重新启动应用程序后也可以使您的购物车物品可用。
  • 您可以将观察者放在表格列更新上,以便增加/减少值将通知 UI 更新项目

【讨论】:

  • 所以您是说我应该将cartItemArrayList 从MakeSales.java 导入我的DetailsActivity.java 并直接从我的+/- 按钮进行更改?如果是这样,那么适配器是如何进来的
  • 不,您不需要从MakeSales.java 导入所有项目,但是您需要更新cartItemArrayList 的正确CartItem 对象,以便更新后的值将在整个应用程序中可用。关于适配器,如果您对适配器的数据集进行任何运行时更改,始终建议使用通知适配器刷新视图,更多详细信息请访问developer.android.com/reference/android/widget/…
猜你喜欢
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多