Получить содержимое EditText, когда пользователь не нажимает кнопку подтверждения программной клавиатуры - PullRequest
0 голосов
/ 05 марта 2019

У меня работает Адаптер, который отображает список продуктов питания, где пользователь должен ввести соответствующую сумму в тексте редактирования.

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);
        }
    });
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...