Search code examples
androidandroid-layoutlistviewsubmenu

how to develop navigation view inside sub navigation view with multiple selection in android?


I am new in Android. I am developing one app in android, Minimum API level is 15 and Maximum API level is 23.
I want like this, and another thing is multiple selection item in sub navigation. When any item is selected from parent navigation view, child navigation view will be open, as shown in image. I search on google but not getting answer. I see this and other so many stack overflow answer but not getting. please if some one help then it's very appreciate.Thanks in advance.

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
            android:id="@+id/lvList"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorPrimary"/>
</LinearLayout>

this is my javafile

public class HomePageActivity extends AppCompatActivity
{

    ListView lvList;

    ArrayList<String> arrayList;
    NavigationViewAdapter adapter;

    ArrayList<RowObject> selectedItemArray;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hope_page);

        lvList = (ListView)findViewById(R.id.lvList);

        setUpListView();

        lvList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        lvList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            for (int i = 0; i < selectedItemArray.size(); i++)
            {
                if (i == position){
                    selectedItemArray.get(position).setSelectedItem(true);
                }else{
                    selectedItemArray.get(i).setSelectedItem(false);
                }
            }
            adapter.notifyDataSetChanged();
        }
    });
    }

    private void setUpListView()
    {
        arrayList = new ArrayList<>();
        selectedItemArray = new ArrayList<>();

        for (int i = 0; i < 20; i++)
        {
            arrayList.add("Item "+(i+1));
            selectedItemArray.add(new RowObject(i, false));
        }
        adapter = new NavigationViewAdapter(HomePageActivity.this, arrayList, selectedItemArray);
        if (adapter != null)
        {
            lvList.setAdapter(adapter);
            adapter.notifyDataSetChanged();
        }
    }
}

This is my adapter

public class NavigationViewAdapter extends BaseAdapter
{
    Activity activity;

    View itemView;
    private LayoutInflater inflater;
    private ViewHolder viewHolder;

    ArrayList<String> arrayList;
    ArrayList<RowObject> selectedItemArray;

    public NavigationViewAdapter(Activity activity, ArrayList<String> arrayList, ArrayList<RowObject> selectedItemArray)
    {
        this.activity = activity;
        this.arrayList = arrayList;
        this.selectedItemArray = selectedItemArray;
        inflater = (LayoutInflater)this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return arrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        try
        {
            itemView = convertView;
            if (convertView == null){
                itemView = inflater.from(parent.getContext()).inflate(R.layout.main_activity_item, parent, false);
                viewHolder = new ViewHolder();

                //if this is first time then inflate view
                viewHolder.itemName = (TextView)itemView.findViewById(R.id.itemName);
                itemView.setTag(viewHolder);
            }else{
                viewHolder = (ViewHolder)itemView.getTag();
            }

            //set Data from ArrayList
            viewHolder.itemName.setText(arrayList.get(position));

            if (selectedItemArray.get(position).isSelectedItem()){
                viewHolder.itemName.setBackgroundColor(activity.getResources().getColor(R.color.colorPrimaryDark));
            }else{
                viewHolder.itemName.setBackgroundColor(activity.getResources().getColor(R.color.colorPrimary));
            }

            notifyDataSetChanged();

            return itemView;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public class ViewHolder
    {
        TextView itemName;
    }
}

this is my RowObject.java

public class RowObject
{
    public int position;
    boolean isSelectedItem;

    public RowObject(int position, boolean isSelectedItem) {
        this.position = position;
        this.isSelectedItem = isSelectedItem;
    }
    public int getPosition() {
        return position;
    }

    public void setPosition(int position) {
        this.position = position;
    }
    public boolean isSelectedItem() {
        return isSelectedItem;
    }

    public void setSelectedItem(boolean isSelectedItem) {
        this.isSelectedItem = isSelectedItem;
    }
}

Solution

  • I think this type of layout is not provided by android but you can fixed using your logic. I think you need to change your xml file, because your listview width is match_parent so your whole screen filled and your second sub menu is not display.Please change that or fix as per your requirement. Your main xml file.

    main_activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical">
    
            <ListView
                android:id="@+id/lvList"
                android:layout_width="100dp"
                android:layout_height="match_parent"
                android:background="@color/colorPrimary"/>
    
            <ScrollView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@+id/lvList"
                android:layout_toEndOf="@+id/lvList">
    
                <LinearLayout
                    android:id="@+id/llItemContainer"
                    android:layout_width="200dp"
                    android:layout_height="50dp"
                    android:orientation="vertical"
                    android:background="@color/input_login_hint">
    
                </LinearLayout>
    
            </ScrollView>
    
        </RelativeLayout>
    
    </LinearLayout>
    

    And add one method in your listview onItemClickListener(). Please see my code.
    java file.

    public class NavigationActivity extends AppCompatActivity
    {
        ListView lvList;
        LinearLayout llItemContainer;
    
        ArrayList<String> arrayList;
        NavigationViewAdapter adapter;
    
        ArrayList<RowObject> selectedItemArray;
        ArrayList<String> selectedSecondItem;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.navigation_activity);
    
            lvList = (ListView)findViewById(R.id.lvList);
    
            setUpListView();
    
            lvList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            llItemContainer = (LinearLayout)findViewById(R.id.llItemContainer);
            lvList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
                    for (int i = 0; i < selectedItemArray.size(); i++)
                    {
                        if (i == position){
                            selectedItemArray.get(position).setSelectedItem(true);
                        }else{
                            selectedItemArray.get(i).setSelectedItem(false);
                        }
                    }
                    adapter.notifyDataSetChanged();
    
                    //here you can pass your sub view item array
                    generateSubView(position);
                }
            });
        }
    
        private void setUpListView()
        {
            arrayList = new ArrayList<>();
            selectedItemArray = new ArrayList<>();
    
            for (int i = 0; i < 20; i++)
            {
                arrayList.add("Item "+(i+1));
                selectedItemArray.add(new RowObject(i, false));
            }
            adapter = new NavigationViewAdapter(NavigationActivity.this, arrayList, selectedItemArray);
            if (adapter != null)
            {
                lvList.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
        }
    
        private void generateSubView(int position)
        {
            try
            {
                selectedSecondItem = new ArrayList<>();
                llItemContainer.removeAllViews();
    
                for (int i = 0; i <= position; i++)
                {
                    final TextView rowText = new TextView(NavigationActivity.this);
                    TableRow.LayoutParams paramsExample = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,
                            147,2.0f);
                    rowText.setId(i);
                    rowText.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
                    rowText.setGravity(Gravity.CENTER_VERTICAL);
                    rowText.setTextColor(getResources().getColor(android.R.color.white));
                    paramsExample.setMargins(3, 3, 3, 3);
                    rowText.setPadding(25, 25, 25, 25);
                    rowText.setTextSize(18);
                    rowText.setText("SecondItem " + i);
                    rowText.setLayoutParams(paramsExample);
    
                    rowText.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            rowText.setBackgroundColor(getResources().getColor(R.color.colorAccent));
    
                            selectedSecondItem.add(rowText.getText().toString());
                        }
                    });
    
                    llItemContainer.addView(rowText);
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    

    you get the selected item from sub navigation view in selectedSecondItem arraylist.