3

What I want to achieve: A java Activity with a belonging xml-layout, where the user can enter the names of all players. Here is how it looks like:

preview

If you click the plus-button you can enter another player (Spieler is german for player). It should be a wrapped view until the maximum height is reached.

I found a very similar question here: How to set a maximum height with wrap content in android?

There is code given with the comment: "you can add this to any view (override onMeasure in a class inherited from a view)"

Here my question: My belonging java-file to the xml-layout inherits from Activiy thus doesnt know the super.onMeasure() method. Do you have any tipps what I can do? Can I have an Activity-java-file and a View-java-file to one layout? Thanks a lot!

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Nina Seil
  • 53
  • 5

2 Answers2

2

You have to create a custom view that extends ScrollView and then use that view in your xml

        public class ScrollViewWithMaxHeight extends ScrollView {

            public static int WITHOUT_MAX_HEIGHT_VALUE = -1;

            private int maxHeight = WITHOUT_MAX_HEIGHT_VALUE;

            public ScrollViewWithMaxHeight(Context context) {
                super(context);

 init(context, null, 0, 0);
            }

            public ScrollViewWithMaxHeight(Context context, AttributeSet attrs) {
                super(context, attrs);
 init(context, attrs, 0, 0);
            }

            public ScrollViewWithMaxHeight(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
 init(context, attrs, defStyle, 0);
            }
           private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes){
    TypedArray a = context.getTheme().obtainStyledAttributes(
                    attrs, R.styleable.custom_ScrollViewWithMaxHeight,  defStyleAttr, defStyleRes);
     maxHeight = 
     a.getDimensionPixelSize(R.styleable.max_height,maxHeight);
        }

            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                try {
                    int heightSize = MeasureSpec.getSize(heightMeasureSpec);
                    if (maxHeight != WITHOUT_MAX_HEIGHT_VALUE
                            && heightSize > maxHeight) {
                        heightSize = maxHeight;
                    }
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.AT_MOST);
                    getLayoutParams().height = heightSize;
                } catch (Exception e) {
                    LogManager.error(this, "onMesure", "Error forcing height", e);
                } finally {
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                }
            }

            public void setMaxHeight(int maxHeight) {
                this.maxHeight = maxHeight;
            }
        }

You also have to create an attrs.xml file in your values folder and add this to it.

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <declare-styleable name="custom_ScrollViewWithMaxHeight">
        <attr name="max_height" format="dimension" />
    </declare-styleable>
</resources>

You can then reference the view like this

<the.package.where.the.view.is.ScrollViewWithMaxHeight
 xmlns:app="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 app:max_height="150dp">
</the.package.where.the.view.is.ScrollViewWithMaxHeight>
Niza Siwale
  • 2,390
  • 1
  • 18
  • 20
  • Hi! Thanks for your answer! I defined this view. Now I want to declare it in my xml-file. I tried this: – Nina Seil Feb 12 '18 at 11:16
  • But where can I define the maxHeight? Do I have to add custom attributes? – Nina Seil Feb 12 '18 at 11:18
  • you have to implement the view you've made not the ScrollView. Look at my edited answer – Niza Siwale Feb 12 '18 at 11:20
  • I have edited my answer again to with the `max_height` attribute – Niza Siwale Feb 12 '18 at 11:33
  • Here is what I did: 1. Create custom View with your code and 2. changing my – Nina Seil Feb 12 '18 at 11:35
  • What do you mean you `cant scroll like before`. Have you also added the attrs xml and also look at the view again, I changed it to implement the `max_height` – Niza Siwale Feb 12 '18 at 11:38
  • Where is the method setMaxHeight() used? I implemented all of this, but it looks exactly like before (with ScrollView) just that I cant scroll (I cannot access the new player when clicking plus) – Nina Seil Feb 12 '18 at 11:47
  • You can call it from your xml `app:max_height="yourMaxHeightInDp"` or call it programmatically – Niza Siwale Feb 12 '18 at 11:49
  • with the new code I get two errors: 1) init(context, 0, 0, 0); --> Error:(19, 23) error: incompatible types: int cannot be converted to AttributeSet and 2) a.getDimensionPixelSize(R.styleable.max_height,maxHeight); --> Error:(35, 52) error: cannot find symbol variable max_height – Nina Seil Feb 12 '18 at 12:03
  • For the first problem I've edited the code, check it again :). For the second one have you created and added the `attrs.xml` to your `values` folder? – Niza Siwale Feb 12 '18 at 12:25
  • yes I did. If I write R.styleable.custom_ScrollViewWithMaxHeight_max_height I dont get any errors, but my app crashes – Nina Seil Feb 12 '18 at 13:01
  • Sorry I didn't mention that it's supposed to be like `R.styleable.custom_ScrollViewWithMaxHeight_max_height` – Niza Siwale Feb 12 '18 at 13:17
  • I forgot to write package com.example.. above my class. So now its working, but I have a "fixed" height so the button is not moving downwards, its underneath the maximum height from the beginning – Nina Seil Feb 12 '18 at 13:31
  • I guess I can make it work later on, but the scrolling with maximum height works now. So thanks!! – Nina Seil Feb 12 '18 at 13:42
0

Its a so simple. instead of use ScrollView, I prefer you have to use the RecycleView, Adapter and for plus icon use Fab button.

Without creating the custom view and all, you can achieve the maximum hight of RecycleView and bottom with Fab button by using theandroid:layout_height="wrap_content" in your .xml file as

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.tejadroid.testing.MainActivity"
    tools:showIn="@layout/app_bar_main">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_item"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clipToPadding="false"
            android:paddingBottom="56dp" />

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|bottom"
            android:layout_margin="@dimen/fab_margin"
            app:srcCompat="@android:drawable/ic_input_add" />
    </FrameLayout>
</RelativeLayout>
TejaDroid
  • 6,561
  • 4
  • 31
  • 38
  • What I want to achieve is that the plus-button is right underneath the last field, if you click "plus", the button goes down, goes down, until its on the bottom and then the scrolling begins. I think its not possible with this suggestion :/ – Nina Seil Feb 12 '18 at 11:24
  • @NinaSeil, Please refer my edited answer of your question, I think now you can achieve you requirement by using this answer. – TejaDroid Feb 12 '18 at 12:21