我有一个包含一堆相对布局的表单,每个布局代表一个组。 这些是两种。一个是过滤器区域,其中包含一个微调器,用于选择过滤器和一个用户输入的编辑框,可以有多个。另一种只有一个实例,并包含一个添加上述类型的按钮。这与父级的底部对齐,父级的底部是包含所有其他布局的相对布局。这也包含在滚动视图中,因此当过滤区域的数量使高度大于屏幕时,它会滚动。我的问题是,一旦我添加了足够的过滤区域以超过屏幕的高度,按钮就会从屏幕移出一次,然后当您向下滚动并再次按下它以添加另一个按钮时,按钮就会停留在屏幕上。就像相对布局不再增长一样。 这是我必须在xml中设置的吗?
原始xml如下:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"> <!--IMPORTANT otherwise backgrnd img. will not fill the whole screen -->
<RelativeLayout
android:id="@+id/searchLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/activity_vertical_margin"
tools:context="com.kadis.materialref.Search">
<RelativeLayout
android:id="@+id/controlArea"
android:layout_width="match_parent"
android:layout_height="@dimen/controlAreaHeight"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/activity_vertical_margin">
<View
android:id="@+id/dividerControl2"
style="@style/Divider"/>
<Button
style="@style/AddButton"
android:id="@+id/addAttributeButton"
android:layout_centerHorizontal="true"
android:layout_width="@dimen/addButtonWidth"
android:layout_height="wrap_content"
android:layout_below="@+id/dividerControl2"
android:onClick="addFilter"
android:text="@string/addSearchAttributeString"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/filterArea0"
android:layout_width="match_parent"
android:layout_height="@dimen/filterLayoutHeight"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="@dimen/filterArea">
<Spinner
android:id="@+id/filterOperatorSelector0"
android:layout_width="@dimen/operatorSpinnerWidth"
android:layout_height="@dimen/filterSpinnerHeight"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<Spinner
android:id="@+id/filterAttributeSelector0"
android:layout_width="wrap_content"
android:layout_height="@dimen/filterSpinnerHeight"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toEndOf="@id/filterOperatorSelector0"
android:layout_toRightOf="@id/filterOperatorSelector0"/>
<EditText
android:id="@+id/filterInput0"
style="@style/SearchFormFieldText"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/filterAttributeSelector0"
android:text="Hello World"/>
</RelativeLayout>
</RelativeLayout>
这是首次打开时的初始屏幕。
屏幕代码如下。
public class Search extends Activity
{
private String[] filterAttributes;
private String[] filterOperators;
private Spinner originalAttributeSelector;
private Spinner originalOperatorSelector;
private int lastAddedFilterAreaId;
// private MultiSelectionSpinner multiSpinner;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
lastAddedFilterAreaId = R.id.filterArea0;
// Get window sizes
DisplayMetrics dm = new DisplayMetrics();
getWindow().getWindowManager().getDefaultDisplay().getMetrics(dm);
int displayWidth = dm.widthPixels;
// Get items in spinners (attributes to search on an doperators to apply).
filterAttributes = getResources().getStringArray(R.array.attributes);
filterOperators = getResources().getStringArray(R.array.operators);
// multiSpinner = (MultiSelectionSpinner) findViewById(R.id.FilterSpinner);
// multiSpinner.setItems(filterAttributes);
originalOperatorSelector = (Spinner) findViewById(R.id.filterOperatorSelector0);
// Add items on the spinner.
ArrayAdapter<String> operatorSpinnerAdapter =
new ArrayAdapter<>(this, R.layout.spinner_item_material_ref, filterOperators);
operatorSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
originalOperatorSelector.setAdapter(operatorSpinnerAdapter);
// Fix the width of the spinner so it doesn't get resized when making selections.
// Get the screen width and subtract the width of the button next to the spinner.
originalAttributeSelector = (Spinner) findViewById(R.id.filterAttributeSelector0);
originalAttributeSelector.getLayoutParams().width = displayWidth - originalOperatorSelector.getWidth();
// Create the adapter containing the list of choices for the spinner (as well the style for it)
// and bind it to the spinner.
ArrayAdapter<String> attributeSpinnerAdapter =
new ArrayAdapter<>(this, R.layout.spinner_item_material_ref, filterAttributes);
attributeSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
originalAttributeSelector.setAdapter(attributeSpinnerAdapter);
originalAttributeSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
// Make the selected text of the spinner slide.
view.setSelected(true);
// Get container, the RelativeLayout.
RelativeLayout filterArea = (RelativeLayout) parent.getParent();
// Get input element, EditText.
View filterInput = filterArea.getChildAt(filterArea.getChildCount()-1);
// Disable the add button if the selected values is the first (Please make a selection)
if (id == 0)
{
((EditText) filterInput).setText("");
filterInput.setEnabled(false);
} else
{
findViewById(R.id.filterInput0).setEnabled(true);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent)
{
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.search, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return id == R.id.action_settings || super.onOptionsItemSelected(item);
}
public void addFilter(View view)
{
// New Relative Layout to be added.
RelativeLayout filterLayout = createFieldArea();
// Add the operator spinner to the filter layout.
Spinner filterOperatorSelector = createFilterOperatorSelector();
filterLayout.addView(filterOperatorSelector);
// Add the attribute spinner to the filter layout, next to the operator spinner.
Spinner filterAttributeSelector = createFilterAttributeSelector(filterOperatorSelector);
filterLayout.addView(filterAttributeSelector);
// Add an Edit Text as the placeholder for the user input in the filter layout, below the attribute spinner.
EditText filterInput = createFilterInputField(filterAttributeSelector);
filterLayout.addView(filterInput);
// Adding the whole filter layout to the search layout (whole screen)
RelativeLayout searchLayout = (RelativeLayout) findViewById(R.id.searchLayout);
searchLayout.addView(filterLayout);
RelativeLayout controlArea = (RelativeLayout) findViewById(R.id.controlArea);
}
private RelativeLayout createFieldArea()
{
// Generate id for new relative layout to be created.
int filterLayoutId = MiscUtils.generateViewId();
RelativeLayout filterLayout = new RelativeLayout(this);
filterLayout.setId(filterLayoutId);
// Define width and height parameters.
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
getResources().getDimensionPixelSize(R.dimen.filterLayoutHeight));
// Define position
rlp.addRule(RelativeLayout.BELOW, lastAddedFilterAreaId);
rlp.addRule(RelativeLayout.ALIGN_PARENT_START);
rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
filterLayout.setLayoutParams(rlp);
// Update which is the latest added filter layout
lastAddedFilterAreaId = filterLayoutId;
return filterLayout;
}
private Spinner createFilterOperatorSelector()
{
Spinner filterOperatorSelector = new Spinner(this);
filterOperatorSelector.setId(MiscUtils.generateViewId());
// Add items on the spinner.
ArrayAdapter<String> spinnerArrayAdapter =
new ArrayAdapter<>(this, R.layout.spinner_item_material_ref, filterOperators);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
filterOperatorSelector.setAdapter(spinnerArrayAdapter);
// Define width and height parameters.
RelativeLayout.LayoutParams rlpSp = new RelativeLayout.LayoutParams(
getResources().getDimensionPixelSize(R.dimen.operatorSpinnerWidth),
getResources().getDimensionPixelSize(R.dimen.filterSpinnerHeight));
// Define position
rlpSp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rlpSp.addRule(RelativeLayout.ALIGN_PARENT_START);
// Set layout parameters
filterOperatorSelector.setLayoutParams(rlpSp);
return filterOperatorSelector;
}
private Spinner createFilterAttributeSelector(Spinner filterOperatorSelector)
{
Spinner filterAttributeSelector = new Spinner(this);
filterAttributeSelector.setId(MiscUtils.generateViewId());
// Add items on the spinner.
ArrayAdapter<String> spinnerArrayAdapter =
new ArrayAdapter<>(this, R.layout.spinner_item_material_ref, filterAttributes);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
filterAttributeSelector.setAdapter(spinnerArrayAdapter);
// Define width and height parameters.
RelativeLayout.LayoutParams rlpSp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
getResources().getDimensionPixelSize(R.dimen.filterSpinnerHeight));
// Define position
rlpSp.addRule(RelativeLayout.ALIGN_PARENT_END);
rlpSp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rlpSp.addRule(RelativeLayout.END_OF, filterOperatorSelector.getId());
rlpSp.addRule(RelativeLayout.RIGHT_OF, filterOperatorSelector.getId());
// Set layout parameters
filterAttributeSelector.setLayoutParams(rlpSp);
return filterAttributeSelector;
}
private EditText createFilterInputField(Spinner filterAttributeSelector)
{
ViewGroup parent = (ViewGroup) filterAttributeSelector.getParent();
EditText filterInput =
(EditText) getLayoutInflater().inflate(R.layout.search_attribute_input, null);
filterInput.setId(MiscUtils.generateViewId());
// Define width and height parameters.
RelativeLayout.LayoutParams rlpET = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
// Define position
rlpET.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rlpET.addRule(RelativeLayout.ALIGN_PARENT_END);
rlpET.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rlpET.addRule(RelativeLayout.ALIGN_PARENT_START);
rlpET.addRule(RelativeLayout.BELOW, filterAttributeSelector.getId());
// Set layout parameters
filterInput.setLayoutParams(rlpET);
return filterInput;
}
}
当我添加填充屏幕的第一个布局时,我向下滚动以找到按钮。
如果我在这里按下添加按钮,则没有任何变化。我从调试器中知道新的布局已经创建,所以我猜它已经不在屏幕上了。