【发布时间】:2016-08-04 20:26:10
【问题描述】:
我一直在开发一个注册表单应用程序,其中使用了一些微调器小部件。微调器用于选择 Country、State 和 City。因此,这些微调器需要以某种方式相互连接(下面的代码将显示我是如何尝试实现的)。
表格代码:
fragment_register.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="true">
<TextView
android:text="Student Registration Form"
android:textSize="22sp"
android:textAlignment="center"
android:layout_marginBottom="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/country_spinner"
android:foregroundTint="#222"
android:background="#001c47"
android:layout_marginBottom="20dp" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/state_spinner"
android:foregroundTint="#222"
android:background="#001c47"
android:layout_marginBottom="20dp" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/city_spinner"
android:foregroundTint="#222"
android:background="#001c47"
android:layout_marginBottom="20dp" />
</LinearLayout>
</ScrollView>
上面的代码有更多的小部件,您可以在 java 文件中找到它们;我没有将它们包含在上面的代码中,因为它会太长。
RegisterFragement.java
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.SharedPreferences;
import android.nfc.Tag;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class RegisterFragment extends Fragment implements View.OnClickListener, Spinner.OnItemSelectedListener{
private AppCompatButton btn_register;
private EditText et_email,et_password,et_name;
private TextView tv_login;
private ProgressBar progress;
//Declaring the Spinners
private Spinner country_spinner;
private Spinner state_spinner;
private Spinner city_spinner;
//An ArrayList for Spinner Items
private ArrayList<String> results;
// countGetData: It will keep a count of how many times get data has been run and for 0 times
// it would set the spinners to default state
private int countGetData;
ArrayList student1 = new ArrayList();
//JSON Array
private JSONArray resultArray;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register,container,false);
initViews(view);
return view;
}
private void initViews(View view){
btn_register = (AppCompatButton)view.findViewById(R.id.btn_register);
tv_login = (TextView)view.findViewById(R.id.tv_login);
et_name = (EditText)view.findViewById(R.id.et_name);
et_email = (EditText)view.findViewById(R.id.et_email);
et_password = (EditText)view.findViewById(R.id.et_password);
progress = (ProgressBar)view.findViewById(R.id.progress);
btn_register.setOnClickListener(this);
tv_login.setOnClickListener(this);
//Initializing the ArrayList
results = new ArrayList<String>();
// Initializing countGetData
countGetData = 0;
//Initializing Spinner
country_spinner = (Spinner) view.findViewById(R.id.country_spinner);
state_spinner = (Spinner) view.findViewById(R.id.state_spinner);
city_spinner = (Spinner) view.findViewById(R.id.city_spinner);
//Adding an Item Selected Listener to our Spinner
//As we have implemented the class Spinner.OnItemSelectedListener to this class iteself we are passing this to setOnItemSelectedListener
country_spinner.setOnItemSelectedListener(this);
state_spinner.setOnItemSelectedListener(this);
city_spinner.setOnItemSelectedListener(this);
university_spinner.setOnItemSelectedListener(this);
college_spinner.setOnItemSelectedListener(this);
ca_spinner.setOnItemSelectedListener(this);
getData("getCountries", "", 0);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_login:
goToLogin();
break;
case R.id.btn_register:
String name = et_name.getText().toString();
String email = et_email.getText().toString();
String password = et_password.getText().toString();
if(!name.isEmpty() && !email.isEmpty() && !password.isEmpty()) {
progress.setVisibility(View.VISIBLE);
registerProcess(name,email,password);
} else {
Snackbar.make(getView(), "Fields are empty !", Snackbar.LENGTH_LONG).show();
}
break;
}
}
private void getData(String urlPart1,String urlPart2, long itemId) {
//Creating a string request
StringRequest stringRequest = new StringRequest(Config.DATA_URL+urlPart1+"&"+urlPart2+"="+itemId,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
resultArray = j.getJSONArray(Config.JSON_ARRAY);
//Calling method getStudents to get the students from the JSON Array
getResults(resultArray);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
//Creating a request queue
RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
//Adding request to the queue
requestQueue.add(stringRequest);
}
private void getResults(JSONArray j) {
//Traversing through all the items in the json array
for (int i = 0; i < j.length(); i++) {
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
//Adding the name of the student to array list
results.add(json.getString(Config.TAG_NAME));
} catch (JSONException e) {
e.printStackTrace();
}
}
if(countGetData == 0) {
student1.add("Select This");
//Setting adapter to show the items in the spinner
country_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, results));
state_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, student1));
city_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, student1));
countGetData += 1;
}
}
//this method will execute when we pic an item from the spinner
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(country_spinner.getSelectedItem().toString().equals("Austria")){
long itemId = country_spinner.getSelectedItemId();
getData("getStates","countryId",itemId);
state_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, results));
}
else{
long itemId = country_spinner.getSelectedItemId();
getData("getStates","countryId",itemId);
state_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, results));
}
}
}
有一个 PHP API 可以根据 url 返回 Country、State 或 City 的 json。例如:
http://www.example.com/location_api/api.php?type=getCountries
http://www.example.com/location_api/api.php?type=getStates&countryId=12
http://www.example.com/location_api/api.php?type=getCities&stateId=1
在 onItemSelected 中,我正在尝试相对于前一个微调器动态设置微调器。对于EX。,我在选择国家/地区旋转器项时设置状态旋转器。我正在通过 if-else 块检查这一点; if 条件检查是否选择了 Austria(列表中的国家之一;随机选择)然后设置 state 微调器 else 还设置 状态微调。这样我最终会根据国家微调器元素设置状态微调器。
为了向 API 指定选择哪个 country,我使用了 itemId,其中包含国家微调器中所选项目的 Id。
long itemId = country_spinner.getSelectedItemId();
然后,当我有 ID 时,我调用设置 result ArraryList 的 getData 方法并将其分配给微调器 state。
getData("getStates","countryId",itemId);
state_spinner.setAdapter(new ArrayAdapter<String>(getActivity().getApplicationContext(), android.R.layout.simple_spinner_dropdown_item, results));
上面的代码使应用程序在运行时崩溃并出现以下错误(我认为只有一部分可能有用,完整的 Logcat 文件在这里:Link):
--------- 崩溃开始 04-13 21:05:09.782 9288-9600/com.gouravchawla.loginregistration E/AndroidRuntime: FATAL 例外:线程 503 进程:com.gouravchawla.loginregistration,PID:9288 java.lang.NegativeArraySizeException:-110 在 com.android.volley.toolbox.DiskBasedCache.streamToBytes(DiskBasedCache.java:316) 在 com.android.volley.toolbox.DiskBasedCache.get(DiskBasedCache.java:117) 在 com.android.volley.CacheDispatcher.run(CacheDispatcher.java:101)
抛出 OutOfMemoryError "未能分配 1667853436 字节 分配 777786 个空闲字节和 381MB 直到 OOM"
【问题讨论】:
标签: java android android-studio android-volley android-spinner