使用滚动视图并以编程方式添加视图

时间:2015-06-05 21:58:36

标签: android android-layout android-scrollview

我有一个包含一堆相对布局的表单,每个布局代表一个组。 这些是两种。一个是过滤器区域,其中包含一个微调器,用于选择过滤器和一个用户输入的编辑框,可以有多个。另一种只有一个实例,并包含一个添加上述类型的按钮。这与父级的底部对齐,父级的底部是包含所有其他布局的相对布局。这也包含在滚动视图中,因此当过滤区域的数量使高度大于屏幕时,它会滚动。我的问题是,一旦我添加了足够的过滤区域以超过屏幕的高度,按钮就会从屏幕移出一次,然后当您向下滚动并再次按下它以添加另一个按钮时,按钮就会停留在屏幕上。就像相对布局不再增长一样。 这是我必须在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>

这是首次打开时的初始屏幕。

Initial screen when opening the app

屏幕代码如下。

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;
    }

}

当我添加填充屏幕的第一个布局时,我向下滚动以找到按钮。 enter image description here enter image description here

如果我在这里按下添加按钮,则没有任何变化。我从调试器中知道新的布局已经创建,所以我猜它已经不在屏幕上了。

0 个答案:

没有答案