Problem # 17 layout_height

1

This error is already looking for it and all the solutions do not work for me, I do not understand what the problem is: Binary XML file line # 17: You must supply to layout_height attribute.

I summarize, I have a BaseActivity class where I have a toolbar and I generate the code of a menu with "onCreateOptionsMenu". The toolbar is for all the activities, so in my BaseActivity I start my toolbar (but depending on a parameter of the child class) Why ?, Why the toolbar I include it in the views ... and where I have an expandable list , I included it in the "header" file and I do not start it in BaseActivity but in the daughter activity itself after listViewMyCoursesBlocks.addHeaderView (header);

Finally, in this activity of the expandable list, when I touch the menu, I get the error and I have no idea how to solve it.

Manifest.xml

<uses-permission android:name="android.permission.INTERNET" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher_saval"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.NoActionBar">
    <activity android:name=".MyCoursesActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".FrontActivity"
        android:configChanges="screenLayout|screenSize"/>
    <activity
        android:name=".LoginActivity"
        android:configChanges="screenLayout|screenSize"/>
    <activity android:name=".MyBlocksActivity"/>
    <activity android:name=".MyClassActivity"/>
    <activity
        android:name=".VideoPlayerActivity"
        android:screenOrientation="sensorLandscape"
        android:configChanges="screenLayout|screenSize"/>
</application>

BaseActivity

public abstract class BaseActivity extends AppCompatActivity

{

protected SessionManager session;

protected final void onCreate(Bundle savedInstanceState, int layoutId, boolean initToolbar)
{
    super.onCreate(savedInstanceState);
    setContentView(layoutId);

    if( initToolbar ){
        initToolBar();
    }

    sesion = SessionManager.getInstance(this);
    //if user is not in sesion, will redirect to frontactivity
    if(!sesion.sesion())
    {
        finish();
    }
}
public void initToolBar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);

    setSupportActionBar(toolbar);

    toolbar.setNavigationIcon(R.drawable.appbar_back);
    toolbar.setOverflowIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.appbar_menu, null));
    if( getSupportActionBar() != null ) {
        getSupportActionBar().setDisplayShowTitleEnabled(false);
    }
}

public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menulateral, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch (item.getItemId())
    {
        case android.R.id.home:
            onBackPressed();
            return true;
        case R.id.cerrarsesion:
            sesion.logout();
            return true;
    }
    return super.onOptionsItemSelected(item);
}
@Override
public void onBackPressed()
{
    if( this.getLocalClassName().equalsIgnoreCase("MyCoursesActivity") )
    {
        final AlertDialog dialog = new AlertDialog.Builder(this)
            .setIcon(R.mipmap.ic_launcher_saval)
            .setTitle("Salir")
            .setMessage("¿Está seguro que desea cerrar su sesión?")
            .setPositiveButton("Aceptar", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    sesion.clearSession();
                    finish();
                }
            })
            .setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // user doesn't want to logout
                }
            })
            .show();
            dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(getResources().getColor(R.color.colorSavalBlue));
            dialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(getResources().getColor(R.color.colorSavalBlue));
    }
    else
    {
        super.onBackPressed();
    }
}

protected Map<String, String> checkParams(Map<String, String> map){
    Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<String, String> pairs = it.next();
        if(pairs.getValue()==null){
            map.put(pairs.getKey(), "");
        }
    }
    return map;
}

}

My second activity which generates the problem at some point:

MyBlocksActivity

public class MyBlocksActivity extends BaseActivity {     private ExpandableListView listViewMyCoursesBlocks;     private ExpandableListAdapter listAdapter;     private Course myCourse;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState, R.layout.activity_my_blocks, false);

    Intent i = getIntent();
    myCourse = i.getExtras().getParcelable("myCourse");

    listViewMyCoursesBlocks = (ExpandableListView) findViewById(R.id.listViewMyCoursesBlocks);

    LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View header = inflater.inflate(R.layout.listexpandable_header, null);
    listViewMyCoursesBlocks.addHeaderView(header);
    //en super.Oncreate pasamos parametro falso ... para indicar si se carga el toolbar en BaseActivity
    //o en la actual
    initToolBar();

    if( !myCourse.getBannerUrl().isEmpty() && myCourse.getBannerUrl() != null )
    {
        ImageView bannerImg = (ImageView) findViewById(R.id.bannerImg);
        Picasso.with(getApplicationContext()).load(myCourse.getBannerUrl()).into(bannerImg);
    }

    //InitData
    initData(new VolleyCallback()
    {
        @Override
        public void onResponse(HashMap<String,List<Activity>> lHash, List<String> lDataHeader)
        {
            listAdapter = new ExpandableListAdapter(getApplicationContext(),lDataHeader,lHash);
            listAdapter.notifyDataSetChanged();
            listViewMyCoursesBlocks.setAdapter(listAdapter);

            if( listAdapter.getGroupCount() == 1 ){
                listViewMyCoursesBlocks.expandGroup(0);
            }
        }
    });

    listViewMyCoursesBlocks.setOnChildClickListener(new ExpandableListView.OnChildClickListener()
    {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id)
        {
            Activity myActivity = (Activity)parent.getExpandableListAdapter().getChild(groupPosition,childPosition);
            if( myActivity.getIsBlocked() == 0 )
            {
                Intent i = new Intent(getApplicationContext(), MyClassActivity.class);
                i.putExtra("myActivity", myActivity);
                startActivity(i);
                return true;
            }
            return  false;
        };
    });
}
public void initData(final VolleyCallback callback)
{
    final List<String> listDataHeader  = new ArrayList<>();
    final HashMap<String,List<Activity>> listHash = new HashMap<>();

    final String url   = Globals.APIACTIVIDADES_URL;
    RequestQueue queue = Volley.getInstance(this).getRequestQueue();
    StringRequest req = new StringRequest(Request.Method.POST, url, new Response.Listener<String>()
    {
        @Override
        public void onResponse(String response)
        {
            try
            {
                JSONObject JSONresponse = new JSONObject(response);
                if ( !JSONresponse.has("error") )
                {
                    int actividadesArr_length = 0;
                    int bloquesActividadesArr_length = 0;
                    int bloquesArr_length = 0;

                    String bannerUrl = JSONresponse.getString("banner");
                    String bloque_nombre = "";

                    if ( JSONresponse.has("actividades") && JSONresponse.get("actividades") instanceof JSONArray )
                    {
                        JSONArray actividadesArr = JSONresponse.getJSONArray("actividades");
                        actividadesArr_length = actividadesArr.length();

                        bloque_nombre = "BLOQUE I";
                        listDataHeader.add(bloque_nombre);

                        List<Activity> actividades = new ArrayList<>();

                        for (int i = 0; i < actividadesArr_length; i++)
                        {
                            JSONObject activity = new JSONObject(actividadesArr.getString(i));
                            Integer id   = activity.getInt("id");
                            String title = activity.getString("titulo");
                            String titlePref = activity.getString("tituloprefijo");
                            String teacher = activity.getString("expositores");
                            Integer isAccomplished = activity.getInt("cumplida");
                            Integer isBlocked = activity.getInt("bloqueo");
                            Integer hvVideo = activity.getInt("tienevideo");
                            String blockName = bloque_nombre;

                            actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo, bannerUrl, blockName));
                        }
                        listHash.put(listDataHeader.get(0),actividades);
                    }
                    if ( JSONresponse.has("bloques") && JSONresponse.get("bloques") instanceof JSONArray )
                    {
                        JSONArray bloquesArr = JSONresponse.getJSONArray("bloques");
                        bloquesArr_length = bloquesArr.length();

                        int ini = 0;
                        if( actividadesArr_length > 0 ){
                            ini = 1;
                        }

                        int romanNumber = 1;
                        for (int i = ini; i < bloquesArr_length; i++)
                        {
                            JSONObject bloque = new JSONObject(bloquesArr.getString(i));
                            String titulo_bloque  = bloque.getString("titulo");

                            bloque_nombre = "BLOQUE " + RomanNumerals.toRoman(romanNumber) + ": " + titulo_bloque;
                            listDataHeader.add(bloque_nombre);

                            List<Activity> actividades = new ArrayList<>();

                            if (bloque.has("actividades") && bloque.get("actividades") instanceof JSONArray)
                            {
                                JSONArray actividadesArr = bloque.getJSONArray("actividades");
                                bloquesActividadesArr_length = actividadesArr.length();

                                for (int j = 0; j < bloquesActividadesArr_length; j++)
                                {
                                    JSONObject activity = new JSONObject(actividadesArr.getString(j));

                                    Integer id   = activity.getInt("id");
                                    String title = activity.getString("titulo");
                                    String titlePref = activity.getString("tituloprefijo");
                                    String teacher = activity.getString("expositores");
                                    Integer isAccomplished = activity.getInt("cumplida");
                                    Integer isBlocked = activity.getInt("bloqueo");
                                    Integer hvVideo = activity.getInt("tienevideo");
                                    String blockName = bloque_nombre;

                                    actividades.add(new Activity(id, titlePref, title, teacher, isAccomplished, isBlocked, hvVideo, bannerUrl, blockName));
                                } //for actividades
                            }
                            romanNumber++;
                            listHash.put(listDataHeader.get(i),actividades);
                        } // for bloques
                    }
                }
                else
                {
                    JSONObject error = JSONresponse.getJSONObject("error");
                    Toast.makeText(getApplicationContext(), "Error: [" + error.getString("num") + "] " + error.getString("msg"), Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e)
            {
                e.printStackTrace();
                Toast.makeText(getApplicationContext(), "Error al recuperar sus datos", Toast.LENGTH_SHORT).show();
            }
            callback.onResponse(listHash, listDataHeader);
        }
    },
    new Response.ErrorListener()
    {
        @Override
        public void onErrorResponse(VolleyError error)
        {
            String message = "Error de conexión";
            if( error.getMessage() != null && !error.getMessage().isEmpty() )
            {
                message += ": [" + error.getMessage() + "]";
            }
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    })
    {
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            HashMap<String, String> user = sesion.getUserDetails();

            // get user data from session
            params.put("sesion", user.get(sesion.getKEY_CODE()));
            params.put("curso", myCourse.getId().toString());
            return checkParams(params);
        }
    };
    queue.add(req);
}

private static class VolleyCallback
{
    void onResponse(HashMap<String,List<Activity>> listHash, List<String> listDataHeader) {

    }
}

}

activity_my_blocks.xml

<?xml version="1.0" encoding="utf-8"?>

    <RelativeLayout
    android:id="@+id/myContent"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center">

    <ExpandableListView
        android:id="@+id/listViewMyCoursesBlocks"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ExpandableListView>

</RelativeLayout>

In this part in MyBlocksActivity I inflate my view "header" and then start toolbar.

View header = inflater.inflate(R.layout.listexpandable_header, null);
    listViewMyCoursesBlocks.addHeaderView(header);
    //en super.Oncreate pasamos parametro falso ... para indicar si se carga el toolbar en BaseActivity
    //o en la actual
    initToolBar();

listexpandable_header.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">

<include layout="@layout/toolbar" android:id="@+id/includetoolbar"/>

<RelativeLayout
    android:id="@+id/myHeader"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="start"
    android:layout_below="@+id/includetoolbar">

    <ImageView
        android:id="@+id/bannerImg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitXY"/>

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/myblocksheader"
        android:textColor="@color/colorSavalBlue"
        android:textSize="20sp"
        android:padding="15dp"
        android:layout_below="@+id/bannerImg"/>
</RelativeLayout>

Toolbar.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbarLayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="top">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="58dp"
android:background="@color/colorWhite"
android:minHeight="@dimen/abc_action_bar_default_height_material"
android:theme="@style/Toolbar">

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:src="@drawable/appbar_logo"/>

    </android.support.v7.widget.Toolbar>
    </RelativeLayout>

Sorry if it is too full of files, I do not know why sometimes the code is cut in the editor, but it is understood I believe.

Any help? This is the error that throws me.

Error

E/AndroidRuntime: FATAL EXCEPTION: main
                                                            java.lang.RuntimeException: Binary XML file line #17: You must supply a layout_height attribute.
                                                                at android.content.res.TypedArray.getLayoutDimension(TypedArray.java:491)
                                                                at android.view.ViewGroup$LayoutParams.setBaseAttributes(ViewGroup.java:5824)
                                                                at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java:5992)
                                                                at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java:610)
                                                                at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:554)
                                                                at android.widget.FrameLayout.generateLayoutParams(FrameLayout.java:56)
                                                                at android.view.LayoutInflater.inflate(LayoutInflater.java:480)
                                                                at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
                                                                at android.support.v7.view.menu.MenuAdapter.getView(MenuAdapter.java:93)
                                                                at android.support.v7.view.menu.MenuPopup.measureIndividualMenuWidth(MenuPopup.java:160)
                                                                at android.support.v7.view.menu.StandardMenuPopup.tryShow(StandardMenuPopup.java:153)
                                                                at android.support.v7.view.menu.StandardMenuPopup.show(StandardMenuPopup.java:187)
                                                                at android.support.v7.view.menu.MenuPopupHelper.showPopup(MenuPopupHelper.java:290)
                                                                at android.support.v7.view.menu.MenuPopupHelper.tryShow(MenuPopupHelper.java:175)
                                                                at android.support.v7.widget.ActionMenuPresenter$OpenOverflowRunnable.run(ActionMenuPresenter.java:803)
                                                                at android.os.Handler.handleCallback(Handler.java:730)
                                                                at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                at android.os.Looper.loop(Looper.java:137)
                                                                at android.app.ActivityThread.main(ActivityThread.java:5103)
                                                                at java.lang.reflect.Method.invokeNative(Native Method)
                                                                at java.lang.reflect.Method.invoke(Method.java:525)
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                                at dalvik.system.NativeStart.main(Native Method)

Just in case, in styles.xml I have

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

</style>

<style name="Toolbar" parent="Theme.AppCompat">

</style>

I'm supposed to enchulate more the toolbar, so I added a style for now blank. And in AppTheme, you do not need to change anything, but as it's called in the manifest, leave it.

I would appreciate it because I have many hours in something "supposedly simple".

Greetings

    
asked by Makeyourmove 10.05.2017 в 22:57
source

1 answer

-1
  

Binary XML file line # 17: You must supply to layout_height attribute.

In most cases, this error is caused because in your layout or view you use the android:layout_width property, but you do not add android:layout_height or the property is misspelled.

    
answered by 10.05.2017 в 23:15