function onTouch() for LinearLayout doesn't work

Viewed 61

I have file FirstLevel where user goes from the main file(mainActivity). I need to add LinearLayouts to the screen in FirstLevel (these LinearLayouts contain two TextViews and are realised in separate XML-file), when user touches the screen. But, actually, nothing happens, I don't see any added LinearLayouts.

public class First_level extends AppCompatActivity implements View.OnTouchListener {
    ImageButton firstButton;
    //boolean flag = true;
    String[] replics  = {...}; //filled massives
    String[] who = {...};
    int i = 0;
    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.first_level);
        LinearLayout gameWindow = findViewById(R.id.mesWin);
        gameWindow.setOnTouchListener(this);
    }

    void npcsay(String text, String hero)
    {
        LinearLayout gameWindow = findViewById(R.id.mesWin);
        LinearLayout view = (LinearLayout) getLayoutInflater().inflate(R.layout.message, gameWindow, false);
        TextView username = view.findViewById(R.id.name);
        username.setText(hero);
        TextView ttxt = view.findViewById(R.id.point);
        ttxt.setText(text);
        gameWindow.addView(view, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    }


    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            npcsay(replics[i], who[i]);
            i++;
            return true;
        }
        return false;
    }

}

First_level.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:id="@+id/gameWindow"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/fillback"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <LinearLayout
        android:id="@+id/mesWin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

</ScrollView>

message.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/message"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginLeft="8dp"
    android:layout_marginTop="4dp"
    android:layout_marginEnd="25dp"
    android:layout_marginRight="25dp"
    android:background="@drawable/grey_background"
    android:orientation="vertical"
    android:padding="5dp">

    <TextView
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/neucha"
        android:padding="5dp"
        android:text="User"
        android:textColor="@color/white"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/point"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/neucha"
        android:padding="5dp"
        android:text="hi"
        android:textColor="@color/black"
        android:textSize="21sp" />

</LinearLayout>

That is how first_level XML looks like.

That is how first_level XML looks like.

2 Answers

Is commonly good pratice to use "ViewGroup.addView(child, LayoutParams)" instead of just "addView()" especially when XML Layout has main ViewGroup set as "width/height: match_parent". Infact default LayoutParams assigned to any inflated View (using "addView(child)" is "wrap_content" for both Widht and Height and in this way the inflated view cannot be measured well and its dimensions will be [0,0].

Please check your XML Layout file: it should be measurable from its own (in other words it should not depends of Parent width/height). If it should depends of Parent's ViewGroup then you cannot use "addView(child)" but you need

  • addView(child, new LinearLayout.LayoutParams(..., ...));

according to your View.

If you're not sure about it please post your XML "R.layout.message" file.

I found your problem.
You set onTouchListener to LinearLayout(R.id.mesWin).
But size of LinearLayout is 0. (Because you set it's size to wrap_content).
So you can fix it by two methods.

First method:
You can change TouchListener to gameWindow.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.first_level);
    View gameWindow = findViewById(R.id.gameWindow);
    gameWindow.setOnTouchListener(this);
}

Second method:

You can change height of LinearLayout(mesWin).
So you need to add fillViewport="true" option to ScrollView

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:id="@+id/gameWindow"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/fillback"
    android:orientation="vertical"
    tools:context=".MainActivity"
    android:fillViewport="true">

    <LinearLayout
        android:id="@+id/mesWin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

</ScrollView>
Related