简体   繁体   中英

Android - how to programmatically add and populate spinners?

I have been looking for quite some time on the web for the most efficient and clean way of programmatically adding elements to views in general in Android but I've never quite found a way for what I am trying to do. As much as I want to use the recommended ways of working (defining layouts in XML files) there are some limitations which I will explain in the next part.

Here's what I am trying to achieve. I have an activity which displays a default view (setContentView is already called in the overwritten onCreate method).

I need to be able to display several "pop-up" style messages, from what I've read, there are two ways to do that, Popups and DialogFragments . The latter seems to be more appropriate for me as I have some specific customization to do in the DialogFragment itself (which is a class separated from my activity extending DialogFragment).

Now, I defined a simple linear layout in an XML document for the dialog fragment but the catch is, I need to add spinners to it, and I never know in advance how many I will need to add (hence, i can't define spinners manually in the XML file).

I've read a bit about inflation but from what I understand, it merely instantiates the view so it becomes "visible" and "manipulable" at runtime but my code does seem to be taken in to account. (The view doesn't display any spinners when the show method is invoked).

Activity class:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    dbSwipeFM = getSupportFragmentManager();
    drawView = new DrawingView(this,dbUtils); 
            [...]
    setContentView(drawView);

    drawView.requestFocus();

}

public void showColumnSelectionDialogFragment(ArrayList<Shape> shapesColToShow){
    new ColumnSelectionDialog().show(dbSwipeFM, "fragment_edit_name");
}

The showColumnSelectionDialogFragment method is invoked from another class.

The ColumnSelectionDialog class [EDIT-last version]:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    //View view = inflater.inflate(R.layout.fragment_edit_name, container);
    View view = new LinearLayout(getActivity());

    DBUtils dbManager = DBUtils.get();

    //to count pairs
    int pairCount = 0;

    LinearLayout horizontalLayoutForTables = new LinearLayout(view.getContext()),
                 horizontalLayoutForCols = new LinearLayout(view.getContext());

    //set layout to be horizontal
    horizontalLayoutForTables.setOrientation(LinearLayout.HORIZONTAL);
    horizontalLayoutForTables.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
    horizontalLayoutForCols.setOrientation(LinearLayout.HORIZONTAL);
    horizontalLayoutForCols.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));

    ArrayList<Shape> dbManagerCurrentlySelectedTables = dbManager.getCurrentRequestSelectedTables();

    ArrayList<String> allAvailableTables = new ArrayList<String>();

    //((LinearLayout) view).addView(new TextView(view.getContext()));
    //get the names of all table elements
    for(int k =0; k < dbManager.getCurrentRequestSelectedTables().size(); k++){
        allAvailableTables.add(dbManager.getCurrentRequestSelectedTables().get(k).getDbElement().getElementName());
    }

    for(int i = 0; i < dbManager.getCurrentRequestSelectedTables().size(); i++){
        if(pairCount >= 1){
            System.out.println("Adding layouts to view");
            ((LinearLayout) view).addView(horizontalLayoutForTables);
            ((LinearLayout) view).addView(horizontalLayoutForCols);
            horizontalLayoutForTables = new LinearLayout(view.getContext());
            horizontalLayoutForCols = new LinearLayout(view.getContext());
            pairCount = 0;
        }
        //create a new spinner containing all the tables
        Spinner tableSpinner = new Spinner(view.getContext());
        tableSpinner.setAdapter(new SelectionDialogSpinnerAdapter(allAvailableTables));

        //create a corresponding spinner for the columns of the current table only.
        Spinner tableColumnSpinner = new Spinner(view.getContext());
        ArrayList<String> columnNamesOnly = new ArrayList<String>();//get the column names only for the spinner
        for(int j = 0; j < dbManagerCurrentlySelectedTables.get(i).getDbElement().getColumns().size(); j++){
            columnNamesOnly.add(dbManagerCurrentlySelectedTables.get(i).getDbElement().getColumns().get(j).getColumnName());
        }
        tableColumnSpinner.setAdapter(new SelectionDialogSpinnerAdapter(columnNamesOnly));

        //add to layout
        System.out.println("Adding spinners to layout");
        horizontalLayoutForTables.addView(tableSpinner);
        horizontalLayoutForCols.addView(tableColumnSpinner);

        pairCount++;
    }

    //view = inflater.inflate(R.layout.fragment_edit_name, container);

    getDialog().setTitle(R.string.joinSelectTitle);

    //view.invalidate();

    this.view = view;       
    return view;
}

This method : getCurrentRequestSelectedTables().size(); will return varying size results depending on end-user interaction.

The view merely displays its title now. So I was thinking, is it simply better to create a brand new activity for this view and then invoke it with an intent from my current activity ? Or is there a way to create a view on the fly (how to pass the context from the activity then to instantiate it?) and add spinners to it programmatically.

Thank you. [Edit]: Note : the linear layouts created inside the DialogFragment must also be programmatically added. XML :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/joinSelectMod"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

</LinearLayout>

Change your onCreateView to this:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_layout_id, container);

LinearLayout viewLayout = (LinearLayout) view.findViewById(R.layout.fragment_edit_name);

 LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT);

DBUtils dbManager = DBUtils.get();

ArrayList<Shape> dbManagerCurrentlySelectedTables = dbManager.getCurrentRequestSelectedTables();

ArrayList<String> allAvailableTables = new ArrayList<String>();

//get the names of all table elements
for(int k =0; k < dbManager.getCurrentRequestSelectedTables().size(); k++){
    allAvailableTables.add(dbManager.getCurrentRequestSelectedTables().get(k).getDbElement().getElementName());
}

for(int i = 0; i < dbManager.getCurrentRequestSelectedTables().size(); i++){
    if(i % 2 == 0){
        LinearLayout horizontalLayoutForTables = new LinearLayout(view.getContext()),
             horizontalLayoutForCols = new LinearLayout(view.getContext());

//set layout to be horizontal
        horizontalLayoutForTables.setOrientantion(LinearLayout.HORIZONTAL);
        horizontalLayoutForCols.setOrientantion(LinearLayout.HORIZONTAL);

        viewLayout.addView(horizontalLayoutForTables);
        viewLayout.addView(horizontalLayoutForCols);

        pairCount = 0;
    }
    //create a new spinner containing all the tables
    Spinner tableSpinner = new Spinner(view.getContext());
    tableSpinner.setAdapter(new SelectionDialogSpinnerAdapter(allAvailableTables));

    //create a corresponding spinner for the columns of the current table only.
    Spinner tableColumnSpinner = new Spinner(view.getContext());
    ArrayList<String> columnNamesOnly = new ArrayList<String>();//get the column names only for the spinner
    for(int j = 0; j < dbManagerCurrentlySelectedTables.get(i).getDbElement().getColumns().size(); j++){
        columnNamesOnly.add(dbManagerCurrentlySelectedTables.get(i).getDbElement().getColumns().get(j).getColumnName());
    }
    tableColumnSpinner.setAdapter(new SelectionDialogSpinnerAdapter(columnNamesOnly));

    //add to layout
    horizontalLayoutForTables.addView(tableSpinner, llp);
    horizontalLayoutForCols.addView(tableColumnSpinner, llp);


}


getDialog().setTitle(R.string.joinSelectTitle);

return view;

}

Update: to include code to set view parameters when put inside new LinearLayout

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM