简体   繁体   中英

Android TextViews clearing when keyboard opens?

I'm new to android and have been playing around with a simple stock-take app and have run in to this issue:

On my "set stock" screen the product list and current stock are grabbed from a database and displayed in 2 columns of TextViews which are generated programmatically.

The onCreate method which grabs from the database and puts it in to the empty ListView in activity_set.xml:

public class SetActivity extends AppCompatActivity{
    private static final String TAG = "SetActivity";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set);

        ArrayList<Product> stock = Products.retrieveProducts(this);
        final ListView mListView = (ListView) findViewById(setList);
        ProductEditAdapter adapter = new ProductEditAdapter(this,R.layout.adapter_set_layout, stock);
        mListView.setAdapter(adapter);

    }

ProductEditAdapter class:

public class ProductEditAdapter extends ArrayAdapter<Product> {
    private static final String TAG = "ProductEditAdapter";
    private Context mContext;
    int mResource;


    public ProductEditAdapter(Context context, int resource, ArrayList<Product> objects){
        super(context,resource,objects);
        mContext = context;
        mResource = resource;

    }

    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String name = getItem(position).getName();
        int stock = getItem(position).getStock();
        Product product = new Product(name,stock);
        LayoutInflater inflater = LayoutInflater.from(mContext);
        convertView = inflater.inflate(mResource, parent, false);
        TextView tvName = (TextView) convertView.findViewById(R.id.pie_name);
        TextView tvCurrentStock = (TextView) convertView.findViewById(R.id.current_stock);
        tvCurrentStock.setText(String.valueOf(stock));
        tvName.setText(name + ":");
        tvCurrentStock.setTag(name);
        return convertView;
    }
}

The adapter_set_layout.xml it is being created with:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/adapsetLayout"
    android:weightSum="100">

    <TextView
        android:gravity="center"
        android:textAlignment="center"
        android:text="TextView1"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:id="@+id/pie_name"
        android:layout_weight="20"
        android:textColor="#000000"
        android:textStyle="bold"
   />

    <TextView
        android:gravity="center"
        android:textAlignment="center"
        android:text="TextView1"
        android:layout_width="match_parent"
        android:layout_height="45dp"
        android:id="@+id/current_stock"
        android:layout_weight="80"
        android:textColor="#000000"
        android:textStyle="bold"
        android:onClick="onClick"
        android:clickable="true"
        />
</LinearLayout>

When you click the stock of an item you're given a popup to enter a new number where you can then click "Ok" to update that TextView or "Cancel" to not.

There's then a submit button which parses through all the TextViews and updates the stock numbers of each product in the database to the new values.

The changed TextView values are temporary until hitting submit, and will revert back to the values they're grabbed from if you leave the screen.

The onClick method in SetActivity:

public void onClick(View v){
    if(v.getId()==R.id.submitButton) {
      confirmDialog();
    }
    else if(v.getId()==R.id.current_stock) {
        LinearLayout parent = (LinearLayout) v.getParent();
        final TextView pie_stock_view = (TextView) parent.findViewById(current_stock);
        final TextView pie_name_view = (TextView) parent.findViewById(pie_name);


        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(pie_name_view.getText().toString());

        final EditText input = new EditText(this);
        input.setInputType(InputType.TYPE_CLASS_NUMBER);
        builder.setView(input);

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                pie_stock_view.setText(input.getText().toString());
            }
        });
        builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        builder.show();


    }
    else if(v.getId()==R.id.resetButton) {
        resetDialog();
    }

}

The app works perfectly in the emulator - when you click a stock number and the box pops up, you can just type with the desktop keyboard and click ok, updating as many values as you want before submitting.

The issue on an actual device is when the box pops up and you click in to it, the on screen keyboard pops up and I guess that counts as leaving the activity because all the updated values are reset back to their generated values, any suggestions how I could go about preventing this?.

You should store the changed values in your array. In order to that first use another function to capture clicks and move the definition of stock Array to outside of onCreate. So you can change your code to this:

public class SetActivity extends AppCompatActivity{
    private static final String TAG = "SetActivity";
    ArrayList<Product> stock = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_set);
        if(stock == null)
            stock = Products.retrieveProducts(this);
        final ListView mListView = (ListView) findViewById(setList);
        ProductEditAdapter adapter = new ProductEditAdapter(this,R.layout.adapter_set_layout, stock);
        mListView.setAdapter(adapter);


        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            public void onItemClick(AdapterView parent, View v, int position, long id){
                if(v.getId()==R.id.submitButton) {
                    confirmDialog();
                }
                else if(v.getId()==R.id.current_stock) {
                    LinearLayout parent = (LinearLayout) v.getParent();
                    final TextView pie_stock_view = (TextView) parent.findViewById(current_stock);
                    final TextView pie_name_view = (TextView) parent.findViewById(pie_name);


                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    builder.setTitle(pie_name_view.getText().toString());

                    final EditText input = new EditText(this);
                    input.setInputType(InputType.TYPE_CLASS_NUMBER);
                    builder.setView(input);

                    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        pie_stock_view.setText(input.getText().toString());
                        getItem(position).setStock(input.getText().toString());
                        }
                    });
                    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                        }
                    });

                    builder.show();

                }
                else if(v.getId()==R.id.resetButton) {
                    resetDialog();
                }

            }
        });
    }
}

Another important thing is try using convertView. It'll prevent memory leak and improve application's performance.

 @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String name = getItem(position).getName();
        int stock = getItem(position).getStock();
        Product product = new Product(name,stock);
        if(convertView != null){
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(mResource, parent, false);
        }
        TextView tvName = (TextView) convertView.findViewById(R.id.pie_name);
        TextView tvCurrentStock = (TextView) convertView.findViewById(R.id.current_stock);
        tvCurrentStock.setText(String.valueOf(stock));
        tvName.setText(name + ":");
        tvCurrentStock.setTag(name);
        return convertView;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM