Android - Неожиданное поведение клавиатуры - EditText в ListView

За последние два дня я столкнулся с проблемой, т.е. создал ListView с Custom View с помощью Variant SubLayout, например:

Product View

Проблемы:

  • Когда я нажимаю EditText Qty, его отображение Soft Input Keyboard с цифровой клавиатурой и сразу же фокус утерян с помощью < edittext с изменением алфавитной клавиатуры. (Первый экранный снимок ниже)

enter image description here

  • В фокусе второго таймера EditText он работает отлично и принимает числовые значения, но при прокрутке клавиатуры изменения от числа до алфавитный. (Второй снимок экрана ниже)

enter image description here

На самом деле я могу понять, проблема в том, что это меняется показывая/скрывая клавиатуру, и из-за этого представления обновляется каждый так что я могу сделать, чтобы сосредоточиться на EditText или предотвратить Обновить представления на Show/Hide Keyboard.

Код моего адаптера:

class MyGridViewAdapter extends BaseAdapter {

    private ArrayList<ProductItems> productItemList;
    private LayoutInflater inflater = null;

    ViewHolder holder;

    double productQtyValue;
    double productRateValue;
    double productDiscountValue;
    double productOfferDiscValue;
    double productDiscountedRateValue;

    double amount;

    public MyGridViewAdapter(ArrayList<ProductItems> productItemsList) {
        // TODO Auto-generated constructor stub
        this.productItemList = productItemsList;
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return productItemList.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return productItemList.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        if (convertView == null) {

            if(isViewWithCatalog)
                convertView = inflater.inflate(R.layout.list_product_view_catalog, null);
            else
                convertView = inflater.inflate(R.layout.list_product_view, null);

            holder = new ViewHolder();

            holder.prodIsNewView    = (ImageView) convertView.findViewById(R.id.productIsNewImageView);
            holder.prodImageView    = (ImageView) convertView.findViewById(R.id.productImage);
            holder.prodNameView     = (TextView) convertView.findViewById(R.id.productNameTextView);
            holder.prodStockView    = (TextView) convertView.findViewById(R.id.productStockTextView);
            holder.prodQtyView      = (EditText) convertView.findViewById(R.id.productQuantityValue);

            holder.prodRateView     = (TextView) convertView.findViewById(R.id.productRateValue);
            holder.prodDiscView     = (TextView) convertView.findViewById(R.id.productDiscountValue);
            holder.prodOfferDiscView= (TextView) convertView.findViewById(R.id.productOfferDiscountTextViewValue);

            holder.prodOriginalRateView = (TextView) convertView.findViewById(R.id.productOriginalRateValue);
            holder.prodPackingQtyView = (TextView) convertView.findViewById(R.id.productBundleQtyView);

            //TextView for Amount
            holder.prodAmountView   = (TextView) convertView.findViewById(R.id.productAmountValue);
            holder.prodPriceTagView = (TextView) convertView.findViewById(R.id.productPriceTagTitle);
            holder.layoutDiscountView = (LinearLayout) convertView.findViewById(R.id.productViewMiddle);

            holder.priceLayoutView1 = (LinearLayout) convertView.findViewById(R.id.productEditTextViewAbove);
            holder.priceLayoutView2 = (LinearLayout) convertView.findViewById(R.id.productViewMiddle);

            holder.prodQtyView.addTextChangedListener(new GeneralTextWatcher(holder));

            convertView.setTag(holder);

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final ProductItems currentProductItem = productItemList.get(position);

        holder.prodId           = currentProductItem.getProdId();
        holder.prodImagePath    = currentProductItem.getProdImagePath();
        holder.prodDesc         = currentProductItem.getProdDesc();
        holder.prodStock        = currentProductItem.getProdStock();
        holder.prodLowStock     = currentProductItem.getProdLowStock();
        holder.prodStockDate    = currentProductItem.getProdStockDate();
        holder.prodPackingQty   = currentProductItem.getProdPackingQty();
        holder.prodIsNew        = currentProductItem.getProdIsNew();
        holder.prodRate         = currentProductItem.getProdRate();
        holder.prodDisc         = currentProductItem.getProdDisc();
        holder.prodOfferDisc    = currentProductItem.getProdOfferDisc();

        holder.prodIsNewView.setVisibility(holder.prodIsNew == 1 ? View.VISIBLE : View.GONE);  

        String medium_path = holder.prodImagePath.isEmpty() ? "" : holder.prodImagePath.replace("product_image/", "product_image/medium/");
        aq.id(holder.prodImageView).image(medium_path, true, true, 0, R.drawable.no_image, BitmapFactory.decodeResource(getResources(), R.drawable.no_image), AQuery.FADE_IN);

        holder.prodImageView.setTag(holder);
        holder.prodImageView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent = new Intent(SelectProductActivity.this, FullScreenImagePreviewActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("position", position);
                intent.putExtra("items", productItemList);
                startActivity(intent);
            }
        });

        /**
         * CHECH WHETHER STOCK IS LESS THAN LOW_STOCK
         */
        if(holder.prodStock <= holder.prodLowStock && isParentNull)
        {
            /** Product Stock for changing with 'k' format if it is greater than 10000 */
            if(holder.prodLowStock > 999999)
                holder.prodStockView.setText(String.valueOf(holder.prodStock).substring(0,3)+"k+");
            else if(holder.prodStock > 99999)
                holder.prodStockView.setText(String.valueOf(holder.prodStock).substring(0,2)+"k+");
            else
                holder.prodStockView.setText(""+holder.prodStock);

            /**
             * Changing BGCOLOR 
             * if stock is less than 0 => red background 
             * else => green background
             */
            holder.prodStockView.setBackgroundResource(holder.prodLowStock <= 0 ? R.drawable.round_corner_red : R.drawable.round_corner_green);
            holder.prodStockView.setVisibility(View.VISIBLE);
        } else {
            holder.prodStockView.setVisibility(View.GONE);
        }

        String code = currentProductItem.getProdCode();
        code = (code.isEmpty() || code.equals("null")) ? "" : "["+code+"] ";
        holder.prodNameView.setText(code + "" +currentProductItem.getProdName());

        Log.w(TAG, "PACKING QTY : "+ holder.prodPackingQty);
        if(holder.prodPackingQty > 0) { //&& isParentNull) {
            holder.prodPackingQtyView.setText("Packing Qty: "+holder.prodPackingQty);
            holder.prodPackingQtyView.setVisibility(View.VISIBLE);
        }
        else 
            holder.prodPackingQtyView.setVisibility(View.INVISIBLE);

        holder.prodQtyView.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // TODO Auto-generated method stub
                if (!hasFocus) {
                    ViewHolder viewHolder = (ViewHolder) v.getTag();
                    saveData(viewHolder);
                }
            }
        });

        holder.prodQtyView.setTag(holder);
        holder.prodRateView.setTag(holder);
        holder.prodDiscView.setTag(holder);
        holder.prodOfferDiscView.setTag(holder);

        productQtyValue = 0.0;
        productRateValue = currentProductItem.getProdRate();
        productDiscountValue = currentProductItem.getProdDisc();
        productOfferDiscValue = currentProductItem.getProdOfferDisc();

        holder.prodRateView.setText(""+new BigDecimal((productRateValue - (productRateValue * (productDiscountValue + productOfferDiscValue) / 100))).setScale(2, RoundingMode.DOWN));

        /** First check whether value of Saved product Array is > 0 or not..*/
        ProductItems savedProdTemp = prodItemsSavedList.get(holder.prodId, null);

        if(savedProdTemp != null)
        {
            productQtyValue = savedProdTemp.getProdQty();
            holder.prodQtyView.setText(""+productQtyValue);
        } else {
            holder.prodQtyView.setText("");
        }

        amount = (productQtyValue * productRateValue) - ((productQtyValue * productRateValue) * ((productDiscountValue + productOfferDiscValue) / 100));

        if(productQtyValue > holder.prodStock && isParentNull) {
            holder.prodQtyView.setTextColor(Color.RED);
            holder.prodQtyView.setBackgroundResource(R.drawable.edittextred_edit_text_holo_light);
        }
        else {
            holder.prodQtyView.setTextColor(Color.BLACK);
            holder.prodQtyView.setBackgroundResource(R.drawable.myactionbar_edit_text_holo_dark);
        }

        holder.prodAmountView.setText("Rs." + new BigDecimal(amount).setScale(2, RoundingMode.CEILING));

        return convertView;
    }

    public class ViewHolder {
        int prodId;
        String prodImagePath;
        String prodDesc;
        double prodRate;
        double prodDisc;
        double prodOfferDisc;
        double prodStock;
        double prodLowStock;
        String prodStockDate;
        double prodPackingQty;
        int prodIsNew;

        ImageView prodIsNewView;
        ImageView prodImageView;
        TextView prodNameView;
        TextView prodStockView;
        EditText prodQtyView;
        TextView prodRateView;
        TextView prodDiscView;
        TextView prodOfferDiscView;

        TextView prodOriginalRateView;
        TextView prodAmountView;
        TextView prodPackingQtyView;
        TextView prodPriceTagView;

        LinearLayout layoutDiscountView;

        LinearLayout priceLayoutView1;
        LinearLayout priceLayoutView2;      
    }
}

Макет деятельности продукта select_product.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/productParentView"
    android:layout_width="fill_parent"
    android:layout_height="match_parent" >

    <Spinner
        android:id="@+id/categorySpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:prompt="@string/prompt_select_category" />

    <ListView
        android:id="@+id/productList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/categorySpinner"
        android:layout_margin="5dp"
        android:descendantFocusability="afterDescendants" 
        android:focusable="false"
        android:layout_marginBottom="10dp"
        android:fastScrollEnabled="true" >
    </ListView>

    <TextView
        android:id="@+id/productIfNoAvailable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:text="@string/error_no_products_available_for_this_category"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@android:color/holo_red_dark"
        android:visibility="gone" />

</RelativeLayout>

XML заголовка заголовка, который используется в getView() list_product_variant_heading_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/productVariantHeadingRelativeLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@drawable/bg_white_shadow"
    android:gravity="center_horizontal"
    android:padding="3dp" >

    <RelativeLayout
        android:id="@+id/layoutProductNameStock"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >

        <RelativeLayout
            android:id="@+id/productNameLayoutInnerForClick"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_toLeftOf="@+id/productIsNewImageView"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/productNameTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/product_name"
                android:textColor="@android:color/black"
                android:textSize="@dimen/product_name_text_size" />
        </RelativeLayout>

        <ImageView
            android:id="@+id/productIsNewImageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginLeft="5dp"
            android:contentDescription="@string/app_name"
            android:src="@drawable/new_icon" />
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/productRowViewLinearLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layoutProductNameStock"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

SubLayouts этой строки продукта создается из следующих файлов.

list_product_variant_single_row_view.xml

list_product_variant_multiple_row_view.xml

Заметил: Просмотр освежает и теряет фокус от edittext, когда клавиатура открыта. почему клавиатура меняет вид с numeric на alphabetic. Я изменил AndroidManifest.xml на android:windowSoftInputMode="stateAlwaysHidden" и android:configChanges="keyboardHidden|orientation" но не работает для меня.

Ваша помощь будет оценена по достоинству.

Ответ 1

Это связано с механизмом рециркуляции listview. Проблема уже поднята в группах google android. Лучше размещать элементы количества при проверке или изменять edittext для выпадания, указывая номера в выпадающих меню.

Проблемы, связанные с EditTexts в ListView (Android)

https://code.google.com/p/android/issues/detail?id=31165

ИЗМЕНИТЬ Он отлично работает с этой опцией:

android:windowSoftInputMode="stateAlwaysHidden|adjustPan"

Ответ 2

Добавьте эту строку в свой код:

input.setRawInputType(Configuration.KEYBOARD_12KEY);

будет отображаться только цифровая клавиатура. проверьте это.