当用户未单击软键盘的确认按钮时,获取EditText内容

时间:2019-03-04 23:11:36

标签: android android-edittext

我正在运行一个适配器,该适配器显示食品列表,用户应该在其中在EditText中输入相应的数量。

enter image description here

如果用户按下软键盘的确认按钮,则一切正常,适配器将通过OnEditorActionListener或什至附加的OnFocusChangeListener正确读取金额。

但是,如果用户直接点击视图的FAB,则不会记录该金额,因为不会调用OnEditorActionListener或OnFocusChangeListener。

在这种非常可能的情况下,如何确保正确记录了金额?

这是我的适配器类代码:

public class FoodCalcAdapter extends RecyclerView.Adapter<FoodCalcAdapter.FoodViewHolder> {
class FoodViewHolder extends RecyclerView.ViewHolder implements AdapterView.OnItemSelectedListener {

    // The views of the food calc item
    private final TextView foodnameView;
    private final EditText amountView;
    private final Spinner typicalAmountSpinner;

    private FoodViewHolder(View itemView) {
        super(itemView);
        foodnameView = itemView.findViewById(R.id.newmeal_foodname);
        typicalAmountSpinner = itemView.findViewById(R.id.newmeal_typicalamountspinner);
        amountView = itemView.findViewById(R.id.newmeal_amount);
        amountView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    int amount = Integer.parseInt(v.getText().toString());
                    storeAmount(amount);
                    return true;
                }
                return false;
            }
        });
        amountView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    String text = ((EditText) v).getText().toString();
                    int amount = Integer.parseInt(text);
                    storeAmount(amount);
                }
            }
        });
    }

    private void storeAmount(int amount) {
        // Store the amount in the first spinner item
        TypicalAmount typicalAmount = (TypicalAmount) typicalAmountSpinner.getItemAtPosition(0);
        typicalAmount.setAmount(amount);

        // ... and store it in the food
        selectedFood.get(getAdapterPosition()).setAmount(amount);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        // On selecting a spinner item, write amount to amount view ...
        TypicalAmount typicalAmount = (TypicalAmount) parent.getItemAtPosition(position);
        amountView.setText(String.valueOf(typicalAmount.getAmount()));

        // ... and store it as amount in the food
        selectedFood.get(getAdapterPosition()).setAmount(typicalAmount.getAmount());

        // If a typical amount (position > 0) is selected, we disable entering text,
        // if custom amount (position == 0) is selected, we enable entering text
        if (position == 0) {
            amountView.setEnabled(true);
            amountView.selectAll();
        } else {
            amountView.setEnabled(false);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        // Nothing to do here
    }
}

private final LayoutInflater mInflater;
private List<Food> selectedFood; // Cached copy of all selected food items

FoodCalcAdapter(Context context) {
    mInflater = LayoutInflater.from(context);
}

@Override
public FoodViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Create the food calc item
    View itemView = mInflater.inflate(R.layout.food_calc_item, parent, false);
    return new FoodViewHolder(itemView);
}

@Override
public void onBindViewHolder(FoodViewHolder holder, int position) {
    if (selectedFood != null) {
        // Get the current food item
        Food food = selectedFood.get(position);

        // Set the food name
        holder.foodnameView.setText(food.getName());

        // Create typical amount spinner
        List<TypicalAmount> typicalAmounts = new ArrayList<>();

        // First entry should always contain the custom amount, which is by default 0 when first used here
        typicalAmounts.add(new TypicalAmount(food.getAmount(), null, mInflater.getContext().getString(R.string.newmeal_customamount)));

        // Append typical amounts
        appendTypicalAmount(typicalAmounts, food.getAmountSmall(), food.getCommentSmall(), mInflater.getContext().getString(R.string.amountsmall_label));
        appendTypicalAmount(typicalAmounts, food.getAmountMedium(), food.getCommentMedium(), mInflater.getContext().getString(R.string.amountmedium_label));
        appendTypicalAmount(typicalAmounts, food.getAmountLarge(), food.getCommentLarge(), mInflater.getContext().getString(R.string.amountlarge_label));

        // Create adapter and add to spinner
        ArrayAdapter<TypicalAmount> typicalAmountAdapter = new ArrayAdapter<>(mInflater.getContext(), R.layout.support_simple_spinner_dropdown_item, typicalAmounts);
        typicalAmountAdapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
        holder.typicalAmountSpinner.setOnItemSelectedListener(holder);
        holder.typicalAmountSpinner.setAdapter(typicalAmountAdapter);

        // Highlight custom amount text to make it easier to edit it
        holder.amountView.selectAll();
    } else {
        // Covers the case no food has been selected (should never happen, we check before)
        holder.foodnameView.setText(mInflater.getContext().getString(R.string.newmeal_nofoodselected));
    }
}

void setSelectedFood(List<Food> selectedFood) {
    this.selectedFood = selectedFood;
}

List<Food> getSelectedFood() {
    return selectedFood;
}

private void appendTypicalAmount(List<TypicalAmount> typicalAmounts, int amount, String comment, String defaultComment) {
    if (amount > 0) {
        typicalAmounts.add(new TypicalAmount(amount, comment, defaultComment));
    }
}

// getItemCount() is called many times, and when it is first called,
// allFood has not been updated (means initially, it's null, and we can't return null)
@Override
public int getItemCount() {
    if (selectedFood != null)
        return selectedFood.size();
    else return 0;
}
}

建议通过单击FAB来检索值,但是我不知道如何处理,因为FAB是在Adapter类之外,周围的Activity类中创建的,因此我无法从中访问单个ViwHolders在适配器内。这是周围活动的代码:

public class NewMealActivity extends AppCompatActivity {

public static final String INTENT_FOODCALC = "FoodCalc";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_meal);

    // Create recycler view
    RecyclerView recyclerView = findViewById(R.id.recyclerview_newmeal);
    final FoodCalcAdapter adapter = new FoodCalcAdapter(this);
    recyclerView.setAdapter(adapter);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    // Pass selected food to adapter
    List<Food> selectedFood = getIntent().getParcelableArrayListExtra(MainActivity.INTENT_FOODLIST);
    adapter.setSelectedFood(selectedFood);

    // Floating action button to calculate meal
    FloatingActionButton fabCalc = findViewById(R.id.fab_calcmeal);
    fabCalc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(NewMealActivity.this, CalcMealActivity.class);

            // Get all selected food, each weighted with its amount
            ArrayList<Food> weightedFood = new ArrayList<Food>(adapter.getSelectedFood());

            // Set to intent
            Intent weightedFoodList = intent.putParcelableArrayListExtra(INTENT_FOODCALC, weightedFood);

            // Start activity
            startActivity(intent);
        }
    });
}
}

0 个答案:

没有答案