java - Android - 类变量未及时分配 setOnItemSelectedListener 的值

标签 java android spinner

我正在编写一个货币转换器应用程序并使用 Volley 请求向 API 发送请求以检索转换率。

我现在有两个微调器(来自货币和目标货币)。我有三个功能,一个用于将项目添加到微调器,一个用于在按下按钮时添加监听器,一个用于发送 volley 请求以检索 JSON 信息。

我相信我正在以正确的顺序调用函数,但是无论出于何种原因,toSpinnerTextfromSpinnerText 的值似乎都没有设置为纺纱厂。在我看来,它们应该在发送对 url 的请求之前设置,因为我在 jsonSendRequest() 之前调用了 addItemsOnToSpinner()。但是当我使用日志调用进行调试时,toSpinnerTextfromSpinnerText 的值在构造 url 字符串时仍然是空字符串。

这是我目前所拥有的。谢谢。

public class MainActivity extends AppCompatActivity {

RequestQueue rq;
Double conversionDouble;

Spinner toSpinner, fromSpinner;
String toSpinnerText = "";
String fromSpinnerText = "";
private Button convertBtn;

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

    addItemsOnToSpinner();
    addListenerOnButton();
    jsonSendRequest();

    Button convertBtn = (Button) findViewById(R.id.convertBtn);
    final EditText fromAmountEditText = findViewById(R.id.fromAmountEditText);

    convertBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            TextView toAmountTextView = findViewById(R.id.toAmountTextView);
            DecimalFormat percentageFormat = new DecimalFormat("0.00");
            Double fromAmount = Double.parseDouble(fromAmountEditText.getText().toString());
            String result = "$" + percentageFormat.format(conversionDouble*fromAmount);
            toAmountTextView.setText(result);
        }
    });
    rq = Volley.newRequestQueue(this);

}

public void jsonSendRequest() {

    RequestQueue queue = Volley.newRequestQueue(this);
    // String url = "http://free.currencyconverterapi.com/api/v3/convert?q=CAD_USD&compact=ultra";
    String url = "http://free.currencyconverterapi.com/api/v3/convert?q=" + fromSpinnerText + "_" + toSpinnerText  + "&compact=ultra";

    // Request a string response
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    JSONObject jsonobject = null;
                    try {
                        jsonobject = new JSONObject(response);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    if (jsonobject.has(fromSpinnerText + "_" + toSpinnerText)) {
                        try {
                            conversionDouble = jsonobject.getDouble(fromSpinnerText + "_" + toSpinnerText);
                            // conversionDouble = jsonobject.getDouble(fromSpinnerText + "_" + toSpinnerText);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

// Add the request to the RequestQueue.
    queue.add(stringRequest);
}

public void addItemsOnToSpinner(){

    Spinner toSpinner = (Spinner) findViewById(R.id.toSpinner);
    Spinner fromSpinner = (Spinner) findViewById(R.id.fromSpinner);

    List<String> currency = new ArrayList<String>();
    currency.add("USD");
    currency.add("CAD");
    currency.add("CNY");

    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
     this, android.R.layout.simple_spinner_item, currency
    );

    dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);


    toSpinner.setAdapter(dataAdapter);
    fromSpinner.setAdapter(dataAdapter);

    fromSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String fromSpinnerText = (String) parent.getItemAtPosition(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

    toSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            String toSpinnerText = (String) parent.getItemAtPosition(position);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    });

}

public void addListenerOnButton() {

    Spinner fromSpinner = (Spinner) findViewById(R.id.fromSpinner);
    Spinner toSpinner = (Spinner) findViewById(R.id.toSpinner);
    Button convertBtn = (Button) findViewById(R.id.convertBtn);

}

}

最佳答案

首先你在评论中提到你不需要 addListenerOnButton()

我已尝试尽可能多地在代码中添加注释,以便您可以关注我所做的更改。

public class MainActivity extends AppCompatActivity {
    //Always create a TAG it is very useful when logging to the logcat!
    private static final String TAG = MainActivity.class.getSimpleName();

    //Not used! Not needed!
    //RequestQueue rq = null;

    // I like to have all my class variables defined at the beginning--even if it is just null!
    //Class variable to hold the object throughout the class!
    Spinner toSpinner = null;
    Spinner fromSpinner = null;
    Button convertBtn = null;

    //Class variable to hold the object throughout the class!
    EditText fromAmountEditText = null;
    TextView toAmountTextView = null;

    String toSpinnerText = "";
    String fromSpinnerText = "";

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

        createSpinnerAddData();

        // convertBtn is a class variable defined above--do not create a local variable here
        convertBtn = (Button) findViewById(R.id.convertBtn);

        // fromAmountEditText is a class variable defined above--do not create a local variable here
        fromAmountEditText = findViewById(R.id.fromAmountEditText);
        // toAmountTextView is a class variable defined above--do not create a local variable here
        toAmountTextView = findViewById(R.id.toAmountTextView);

        convertBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Perform your request here--after the currencies have been selected!
                jsonSendRequest();
            }
        });
        //Dont use it--Dont need it!
        //rq = Volley.newRequestQueue(this);
    }

    // this does not need to be public!
    private void jsonSendRequest() {

        RequestQueue queue = Volley.newRequestQueue(this);
        // String url = "http://free.currencyconverterapi.com/api/v3/convert?q=CAD_USD&compact=ultra";
        String url = "http://free.currencyconverterapi.com/api/v3/convert?q=" + fromSpinnerText + "_" + toSpinnerText  + "&compact=ultra";

        // Request a string response
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //onResponse is asynchronous it is called when the data is available, but it executes on the UI thread 
                        JSONObject jsonobject = null;
                        try {
                            jsonobject = new JSONObject(response);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        if (jsonobject.has(fromSpinnerText + "_" + toSpinnerText)) {
                            try {
                                //conversionDouble is only used here so it can be a local variable!
                                Double conversionDouble = jsonobject.getDouble(fromSpinnerText + "_" + toSpinnerText);
                                // conversionDouble = jsonobject.getDouble(fromSpinnerText + "_" + toSpinnerText);

                                //now the data has returned from the async request and is ready to be used..
                                //...do the conversion, now!
                                DecimalFormat percentageFormat = new DecimalFormat("0.00");
                                Double fromAmount = Double.parseDouble(fromAmountEditText.getText().toString());
                                String result = "$" + percentageFormat.format(conversionDouble*fromAmount);
                                toAmountTextView.setText(result);

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });

        // Add the request to the RequestQueue.
        queue.add(stringRequest);
    }

    // this does not need to be public!
    private void createSpinnerAddData(){

        //The spinners were already defined in the onCreate method--please do not create local variables!!
        //Spinner toSpinner = (Spinner) findViewById(R.id.toSpinner);
        //Spinner fromSpinner = (Spinner) findViewById(R.id.fromSpinner);

        // fromSpinner is a class variable defined above--do not create a local variable here
        fromSpinner = (Spinner) findViewById(R.id.fromSpinner);
        // toSpinner is a class variable defined above--do not create a local variable here
        toSpinner = (Spinner) findViewById(R.id.toSpinner);

        List<String> currency = new ArrayList<String>();
        currency.add("USD");
        currency.add("CAD");
        currency.add("CNY");

        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, currency);

        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

        toSpinner.setAdapter(dataAdapter);
        fromSpinner.setAdapter(dataAdapter);

        fromSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //This has also been defined as a class variable--please do not create local variable!!
                //String fromSpinnerText = (String) parent.getItemAtPosition(position);
                //...Instead use the class variable
                fromSpinnerText = (String) parent.getItemAtPosition(position);
                Log.e(TAG, "fromSpinnerText = " + fromSpinnerText);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        toSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //Same principle as above
                toSpinnerText = (String) parent.getItemAtPosition(position);
                Log.e(TAG, "toSpinnerText = " + toSpinnerText);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

}

在上面的评论中也提到:了解publicprotectedprivate 方法和变量之间的区别非常重要,因为以及变量的范围......何时使用类变量和局部变量。作为一名程序员,这将对您大有裨益!祝你好运,继续学习!

如果您有任何问题 -- 我会尽力提供帮助。

关于java - Android - 类变量未及时分配 setOnItemSelectedListener 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50669590/

相关文章:

java - java的.asparallel()方法中的 'batchsize'是什么

java - 根据token延迟提交任务

java - Android - 发送 HDMI CEC 命令到电视 - minix - libCEC

Angular 5 Material Spinner 不工作

android - 如何在没有微调器的情况下像微调器一样弹出列表?

java - 如何从Java中的父类(super class)访问私有(private)值?

java - 为什么上传图片到Blobstore后回调失败?

android - 如何修复 "Failed to install ' cordova-plugin-console' :Error "

android - 有没有办法通过 WebRTC 在 Android 中捕获/共享自己的应用程序屏幕?

android - Spinner.setSelection 没有正确触发 OnItemSelectedListener