0

I have a DrawerLayout, which uses 2 Layouts.

  1. for the main content. (RelativeLayout)
  2. The drawer pane. (LinearLayout)

I need to create everything DYNAMCALLY, so no XML has to be used.

This is the code to create the drawerPane:

public class Test2 extends AppCompatActivity{

    ListView myList;
    DrawerLayout drawerLayout;

    LinearLayout drawerPane;
    RelativeLayout content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myList=new ListView(this);

        drawerLayout=new DrawerLayout(this);

        DrawerLayout.LayoutParams drawerLayout_params=new DrawerLayout.LayoutParams(280, DrawerLayout.LayoutParams.MATCH_PARENT);

        drawerLayout.setId(0);

        drawerPane=new LinearLayout(this);
        drawerPane.setGravity(Gravity.START);
        drawerPane.setClickable(true);

        myList=new ListView(this);

        myList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(280,LinearLayout.LayoutParams.MATCH_PARENT);
        lp.gravity=Gravity.START;

        drawerPane.setLayoutParams(lp);

        drawerPane.addView(myList,new ListView.LayoutParams(280,ListView.LayoutParams.MATCH_PARENT));

        drawerPane.setGravity(Gravity.START);
        drawerPane.setOrientation(LinearLayout.VERTICAL);

        setContentView(drawerLayout,drawerLayout_params);

        content=new RelativeLayout(this);

        drawerLayout.addView(content,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        drawerLayout.addView(drawerPane,lp);

        LinkedList<String> list=new LinkedList<>();

        list.add("Item #1");
        list.add("Item #2");
        list.add("Item #3");

        myList.setAdapter(new My_Adapter<String>(this,R.layout.drawer_item,list) {
            @Override
            protected void set(String item, View customView) {

                TextView title=(TextView)customView.findViewById(R.id.title);
                TextView subTitle=(TextView)customView.findViewById(R.id.subTitle);

                title.setText(item);
                subTitle.setText(item);
            }
        });
    }
}

I use a My_Adapter custom class for the adapter of my ListView:

public abstract class My_Adapter<T> extends BaseAdapter {

    private int customLayoutID;

    private Context myContext;

    private Collection<T> listValues;
    private T[] arrayValues;

    private final boolean listMode;
    private final boolean arrayMode;

    public My_Adapter(Context context,int layoutID, T[] values) {

        arrayMode=true;
        listMode=false;

        myContext=context;
        arrayValues=values;
        customLayoutID=layoutID;
    }

    public My_Adapter(Context context,int layoutID, Collection<T> values) {

        listMode=true;
        arrayMode=false;

        myContext=context;
        listValues=values;
        customLayoutID=layoutID;
    }

    @Override
    public int getCount() {

        if (listMode){

            return listValues.size();
        }
        else if (arrayMode){

            return arrayValues.length;
        }
        else return -1;
    }

    @Override
    public T getItem(int position) {

        if (listMode){

            return ((List<T>) listValues).get(position);
        }
        else if (arrayMode){

            return arrayValues[position];
        }
        else return null;
    }

    @Override
    public long getItemId(int position) {

        return position;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater= LayoutInflater.from(myContext);

        View myView= inflater.inflate(customLayoutID,parent,false);

        T item=getItem(position);

        set(item,myView);

        return myView;
    }

    protected abstract void set(T item, View customView);
}

With this code, this is what the app looks like:

Application preview

This is the drawer_item.xml file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="10dp"
    android:paddingBottom="10dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:gravity="center_vertical"
        android:textColor="@color/abc_primary_text_material_dark"
        android:text="Line 1"
        android:textStyle="bold" />

    <TextView android:id="@+id/subTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Line 2"
        android:textColor="#717171"
        android:layout_below="@+id/title"
        android:layout_alignRight="@+id/title"
        android:layout_alignEnd="@+id/title" />

</RelativeLayout>

EDIT/UPDATE

I want to get the same result i get with the following xml code. Look the "LAYOUT_GRAVITY" for the LinearLayout.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- The main content view -->
    <RelativeLayout
        android:id="@+id/mainContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

    </RelativeLayout>

    <!-- The navigation drawer -->
    <LinearLayout
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:id="@+id/drawerPane"
        android:layout_gravity="start"
        android:clickable="true"
        android:orientation="vertical">

        <!-- Profile Box -->

        <RelativeLayout
            android:id="@+id/profileBox"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@color/material_blue_grey_900"
            android:padding="8dp" >

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="42dp"
                android:layout_centerVertical="true"
                android:layout_marginLeft="15dp"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/userName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="ElektroFR"
                    android:textColor="#fff"
                    android:textSize="16sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/desc"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/userName"
                    android:layout_marginTop="4dp"
                    android:text="View Profile"
                    android:textColor="#fff"
                    android:textSize="12sp" />
            </LinearLayout>
        </RelativeLayout>

        <!-- List of Actions (pages) -->
        <ListView
            android:id="@+id/navList"
            android:layout_width="280dp"
            android:layout_height="match_parent"
            android:layout_below="@+id/profileBox"
            android:choiceMode="singleChoice"
            android:background="@color/bright_foreground_disabled_material_light" />

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
Francesco Rizzi
  • 631
  • 6
  • 24
  • No XML, but you have a drawer_item.xml? :) – OneCricketeer Jun 16 '16 at 17:51
  • @cricket_007 this has to be the only "static" element in my project :) – Francesco Rizzi Jun 16 '16 at 17:54
  • I see. Regarding your problem, I do not think layout gravity plays nicely with RelativeLayout. Since you seem not to need anything being relative, I would suggest a LinearLayout for the `drawerPane` – OneCricketeer Jun 16 '16 at 18:17
  • @cricket_007 Yes, but i can't accept that writing this on xml makes things work fine. It's really annoying. Why does not exist a method to set layout_gravity? – Francesco Rizzi Jun 16 '16 at 18:20
  • So you need a way to set a layout gravity for views inside a RelativeLayout ? This is not the way RelativeLayout works. What's your final goal ? – doubotis Jun 16 '16 at 18:23
  • I think you may have misunderstood. The content can be a RelativeLayout, but DrawerPane should be something like a simple ListView or a LinearLayout and on **that** there should be `Gravity.START | Gravity.LEFT` – OneCricketeer Jun 16 '16 at 18:27
  • @doubotis i'm new to android and i noticed that using relativelayout in a xml file works just fine by setting "android:layout_gravity". Now i want to replicate that by code. – Francesco Rizzi Jun 16 '16 at 18:31
  • @cricket_007 i'll try to use a linear layout... but i'm pretty unsatisfied :( – Francesco Rizzi Jun 16 '16 at 18:32
  • It may be helpful if you provided the XML that you think works in your question. `setGravity` is not for the `layout_gravity` attribute – OneCricketeer Jun 16 '16 at 18:39
  • @cricket_007 done, hope it helps, check for updates in the post – Francesco Rizzi Jun 16 '16 at 18:51
  • I see. Well, 1) A LinearLayout would serve better because all you have is a layout_below for the ListView. 2) `setGravity` on the RelativeLayout is not what you need. Please see this post http://stackoverflow.com/a/8049860/2308683 – OneCricketeer Jun 16 '16 at 18:54
  • @cricket_007 ok... so no hope for this to be done programmatically, frustrating...so should i use a linear layout, right? I'm such a newbie on android programming... how can i set layout_gravity if it is not possible programmatically? – Francesco Rizzi Jun 16 '16 at 19:20
  • No, look at the link, it is possible programmatically, you just need to set the gravity on the LayoutParams instead of using the `setGravity` method on the layout itself. – OneCricketeer Jun 16 '16 at 20:07
  • @cricket_007 but i can't use it with relativelayout.layoutparams, since it is not implemented.. so i definitely must change layout, right? – Francesco Rizzi Jun 16 '16 at 20:18
  • There is no access to `params.gravity = Gravity.START`? – OneCricketeer Jun 16 '16 at 20:22
  • @cricket_007 not for the relative ones – Francesco Rizzi Jun 16 '16 at 20:25
  • In that case, then LinearLayout it is. Should just be as simple as `drawerPane=new LinearLayout(this);`, plus some other things – OneCricketeer Jun 16 '16 at 20:47
  • @cricket_007 i'll check this out... thanks for you patience – Francesco Rizzi Jun 16 '16 at 20:49
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114880/discussion-between-francesco-rizzi-and-cricket-007). – Francesco Rizzi Jun 16 '16 at 21:32

3 Answers3

0

Instead of setting the layout params of the view before you add it to the parent group, use the version of addView that takes a LayoutParam parameter in addition to the View.

Also, FWIW, it's not recommended to use the position value for the item id.

cwbowron
  • 1,015
  • 6
  • 10
  • Thanks for the answer but I modified the code as you said and nothing changed. Please note that, if i use xml, and use "gravity" instead of "layout_gravity" the result looks the same – Francesco Rizzi Jun 16 '16 at 18:01
0

SOLUTION THANKS TO THIS QUESTION ANSWER!:

SOLUTION

You have to use DrawerLayout.LayoutParams for every view which will be used by the drawer!

  1. the drawerpane
  2. the listView

This is the final code:

package elektro_fr.newapplication;

public class Test2 extends AppCompatActivity{

    ListView myList;
    DrawerLayout drawerLayout;

    LinearLayout drawerPane;
    RelativeLayout content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        myList=new ListView(this);

        drawerLayout=new DrawerLayout(this);

        DrawerLayout.LayoutParams drawerLayout_params=new DrawerLayout.LayoutParams(My_AndroidTools.DisplayTools.getPixelsDimension(getResources(),180), DrawerLayout.LayoutParams.MATCH_PARENT);
        drawerLayout_params.gravity=Gravity.START;

        drawerLayout.setId(0);

        drawerPane=new LinearLayout(this);
        drawerPane.setGravity(Gravity.START);
        drawerPane.setClickable(true);

        myList=new ListView(this);

        myList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

        drawerPane.setLayoutParams(drawerLayout_params);

        drawerPane.addView(myList,drawerLayout_params);

        drawerPane.setOrientation(LinearLayout.VERTICAL);

        setContentView(drawerLayout,drawerLayout_params);

        content=new RelativeLayout(this);

        drawerLayout.addView(content,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        drawerLayout.addView(drawerPane,drawerLayout_params);

        LinkedList<String> list=new LinkedList<>();

        list.add("Item #1");
        list.add("Item #2");
        list.add("Item #3");

        myList.setAdapter(new My_Adapter<String>(this,R.layout.drawer_item,list) {
            @Override
            protected void set(String item, View customView) {

                TextView title=(TextView)customView.findViewById(R.id.title);
                TextView subTitle=(TextView)customView.findViewById(R.id.subTitle);

                title.setText(item);
                subTitle.setText(item);
            }
        });
    }
}
Community
  • 1
  • 1
Francesco Rizzi
  • 631
  • 6
  • 24
0
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_device_list);

    //=========================Adding Toolbar in android layout======================================
    Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(myToolbar);

    //=========================Toolbar End============================================================


    /***************************************************************************************
     * Navigation Drawer Layout
     *
     ***************************************************************************************/
    // drawer layout instance to toggle the menu icon to open
    // drawer and back button to close drawer
    drawerLayout = findViewById(R.id.draw_layout);
    actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.nav_open, R.string.nav_close);

    // pass the Open and Close toggle for the drawer layout listener
    // to toggle the button
    drawerLayout.addDrawerListener(actionBarDrawerToggle);
    actionBarDrawerToggle.syncState();

    mNavigationView =  findViewById(R.id.nav_view);
    mNavigationView.setNavigationItemSelectedListener(this);

    // to make the Navigation drawer icon always appear on the action bar
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
   /***************************************************************************************
    * Navigation Drawer Layout
    *
    ***************************************************************************************/


}

Using this link: https://timxn.com/en/programmatically-add-navigation-drawer-android

ranojan
  • 819
  • 8
  • 11