我正在尝试使用自定义对话框来自动填充包含Google Places API中地名的表单字段。
我编写的代码在Dialog片段之外工作,但它在对话框中给出了一个模糊的错误(即java.lang.RuntimeException: Binary XML file line #8: You must supply a layout_height attribute.
)
我一直在四处寻找,我认为这个错误只是一个级联的结果,这是由于我做错了一些基本原因造成的。
任何帮助都将不胜感激,我很乐意提供进一步的澄清。
我的自定义对话框:
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.fragment_location_picker, null);
mCityView = (DelayAutoCompleteTextView) view.findViewById(R.id.trip_city);
mCityView.setAdapter(new PlacesAutoCompleteAdapter(getActivity(), R.layout.list_item));
mCityView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String[] destination = adapterView.getItemAtPosition(position).toString().split(",");
DelayAutoCompleteTextView city = (DelayAutoCompleteTextView) view.findViewById(R.id.trip_city);
EditText country = (EditText) view.findViewById(R.id.trip_country);
city.setText(String.valueOf(destination[0]));
country.setText(String.valueOf(destination[1]));
}
});
builder.setView(view)
// Add action buttons
.setPositiveButton(R.string.confirm_location, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LocationPickerFragment.this.getDialog().cancel();
}
});
return builder.create();
}
我的自定义自动整理视图:
public class DelayAutoCompleteTextView extends AutoCompleteTextView {
private static final int MESSAGE_TEXT_CHANGED = 100;
private static final int DEFAULT_AUTOCOMPLETE_DELAY = 750;
private int mAutoCompleteDelay = DEFAULT_AUTOCOMPLETE_DELAY;
private ProgressBar mLoadingIndicator;
private final Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {
DelayAutoCompleteTextView.super.performFiltering((CharSequence) msg.obj, msg.arg1);
}
};
public DelayAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setLoadingIndicator(ProgressBar progressBar) {
mLoadingIndicator = progressBar;
}
public void setAutoCompleteDelay(int autoCompleteDelay) {
mAutoCompleteDelay = autoCompleteDelay;
}
@Override protected void performFiltering(CharSequence text, int keyCode) {
if (mLoadingIndicator != null) {
mLoadingIndicator.setVisibility(View.VISIBLE);
}
mHandler.removeMessages(MESSAGE_TEXT_CHANGED);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_TEXT_CHANGED, text), mAutoCompleteDelay);
}
@Override public void onFilterComplete(int count) {
if (mLoadingIndicator != null) {
mLoadingIndicator.setVisibility(View.GONE);
}
super.onFilterComplete(count);
}
}
我的自定义位置自动完成适配器:
public class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> resultList;
public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
@Override
public int getCount() {
return resultList.size();
}
@Override
public String getItem(int index) {
return resultList.get(index);
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
}
else {
notifyDataSetInvalidated();
}
}};
}
private ArrayList<String> autocomplete(String input) {
ArrayList<String> resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
URL url = new URL(Config.PLACES_API_BASE + Config.TYPE_AUTOCOMPLETE + Config.OUT_JSON + "?sensor=false&key=" + Config.GOOGLE_API_KEY + "&input=" + URLEncoder.encode(input, "utf8") + "&types=(cities)");
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
Log.e(Config.LOG_TAG, "Error processing Places API URL", e);
return resultList;
} catch (IOException e) {
Log.e(Config.LOG_TAG, "Error connecting to Places API", e);
return resultList;
} finally {
if (conn != null) {
conn.disconnect();
}
}
try {
// Create a JSON object hierarchy from the results
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
// Extract the Place descriptions from the results
resultList = new ArrayList<String>(predsJsonArray.length());
for (int i = 0; i < predsJsonArray.length(); i++) {
resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
}
} catch (JSONException e) {
Log.e(Config.LOG_TAG, "Cannot process JSON results", e);
}
System.out.println("RESPONSE LIST:"+resultList);
return resultList;
}
}
我从活动中初始化对话框的地方:
mLocationSelect = (Button) findViewById(R.id.trip_location_button);
mLocationSelect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DialogFragment locationPicker = new LocationPickerFragment();
locationPicker.show(getFragmentManager(), null);
}
});
对话框片段布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:src="@drawable/ic_action_place"
android:layout_width="match_parent"
android:layout_height="64dp"
android:scaleType="center"
android:background="#FFFFBB33"
android:contentDescription="@string/app_name" />
<com.responseapp.android.ui.common.DelayAutoCompleteTextView
android:id="@+id/trip_city"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="@string/trip_city"
android:layout_marginTop="16dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="4dp"/>
<EditText
android:id="@+id/trip_country"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/trip_country"
android:layout_marginTop="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginBottom="16dp"
android:fontFamily="sans-serif"/>
答案 0 :(得分:1)
解决方案由pskink
提供原来我需要更改list_item.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_dropdown"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?attr/dropdownListPreferredItemHeight"
android:ellipsize="marquee"
android:textColor="#000"
android:textAlignment="inherit"/>
对此:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_dropdown"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="marquee"
android:textColor="#000"
android:textAlignment="inherit"/>