Android: Problem by using a class from xml.file when called from fragment-

for a uni project I need to integrate certain android apps together and I did it in the past with fragments, but the other project workers did it with a seperate activity. When I try to integrate their work, by recreating/handling everything now as a fragment (instead of their activity), I run into problems with a class inside the .xml file of their work. Their task was a touch-based game, for which they created the “Touchinput_Fragment” class. It shows a field, in which things should be displayed to “cross” out. The actual game should be done inside the fragment “OStrikeThroughFragment”. There is also the “Touchinput_Fragment” class, which causes me the problems when I try to handle it with the Fragment “OStrikeThroughFragment”. The other people used an acitivty, where this “Touchinput” class and view seems to be running normal.

I receive/have the following errors:

  • When i try to start the actual “OStrikeThroughFragment” game, the “Touchinput_Fragment” cannot be cast to the class it should be ?

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.metaapptablet, PID: 7719 java.lang.ClassCastException: com.example.metaapptablet.pepperstrike.TouchInput_Fragment cannot be cast to com.example.metaappragtablet.FragmentFputersThrke$Instagram com.example.metaapptablet.pepperstrike.OStrikeThroughFragment.initialize(OStrikeThroughFragment.java:302)

  • When I start the “OStrikeThroughFragment”, its actual view seems to get initialized 2x in the debugger?

I tried some other things, but it sometimes appears to me, that the class “Touchinput_Fragment” gets destroyed ? When I later try to refer to it, I got a Nullpointerexception. (Not a part of this code here). Does it get created every time i refer/call it ?

I needed to take out a lot of the code from the files, so they are not the complete classes.

Some hints, why such a class inside a fragment – .xml file creates such problems and how to solve it, are super appreaciated 🙂 Thanks in advance!

Mainactivity.java

(only the part, where I want to start the fragment with the game)[The Mainactivity, from where I start all Fragments, does not contain any parts of the fragment layout elements]

OStrikeThroughFragment fragment_crossout = new OStrikeThroughFragment();

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.view, fragment_crossout, "layout_crossout_normal")
                    .commit();

OStrikeThroughFragment

  public class OStrikeThroughFragment extends Fragment {


 View view;

boolean onCreate                = false;
boolean intitialize             = false;



int [][] rasterO;
int [][] rasterO24;
int [][] rasterO16;
int [][] rasterO9;
int [] varying_OArray = new int[]{
        1,2,1,1,2,3,1,2,3,1,2,2,2,
        1,1,1,1,2,1,1,1,1,1,2,1,2,
        1,3,2,1,3,2,1,1,2,1,3,1,2,
        1,3,2,1,1,3,2,1,1,2,3,1,2,
        3,2,1,3,1,1,2,1,1,2,1,1,3,
        1,1,2,1,1,3,1,3,1,1,2,1,2,
        2,3,2,1,3,1,3,1,2,1,1,2,1,
        1,3,3,2,1,3,1,1,1,1,2,2,1,
        1,1,1,3,1,1,2,2,2,1,1,1,3,
        2,1,3,3,1,1,3,1,1,2,1,2,1,
        1,2,1,1,1,3,1,2,1,1,3,1,2,
        2,1,2,3,1,1,1,1,3,2,1,3,1
};
int mode = 0; // mode 0 for normal O-mode; mode 1 for varying O-mode;
ArrayList<ImageView> images = new ArrayList<>();
ArrayList<ImageView> blanks = new ArrayList<>();
CountDownTimer countDownTimer;
TouchInput_Fragment touch;

TextView points;
TextView time;
int score =0;
int lastScore = 0;
int pxpcm = 0;
int rownumber, columnnumber;
Menu main_menu;
int exercise_counter = 0;
int exercise_repetition_number = 4;
int escalation_level = 0;
boolean hint_sent = false;


MQTT mqtt;
String topic = "pepper";

String ipAddress;

public OStrikeThroughFragment() {
    // Required empty public constructor
}


public static OStrikeThroughFragment newInstance(String param1, String param2) {
    OStrikeThroughFragment fragment = new OStrikeThroughFragment();
    Bundle args = new Bundle();

    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //super.onCreate(null);
    if (getArguments() != null) {

    }




}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    //inflater.getContext().setTheme(R.style.AppTheme_NoActionBar);
     view = inflater.inflate(R.layout.fragment_o_strike_through,container,false);

    pxpcm = pixelProCm();
    generateGrid();
    initialize(false);
    setClickListener();


    time = view.findViewById(R.id.timeDisplay);
    time.setText(String.format(getResources().getString(R.string.time), 60));
    points = view.findViewById(R.id.pointsDisplay);
    points.setText(String.format(getResources().getString(R.string.points) , 0));

    rasterO = rasterO24; //TODO Provisorium
    container.addView(touch);
    return view;
}







public void displayData(){
    DisplayMetrics metrics = getResources().getDisplayMetrics();

    float density = metrics.density;
    float dpix = metrics.xdpi;
    float dpiy = metrics.ydpi;



    Point size = new Point();
    getActivity().getWindowManager().getDefaultDisplay().getRealSize(size);
    System.out.println("Display Auflösung: " + size.x + " x " + size.y);

    double x = size.x/dpix;
    double y = size.y/dpiy;

}

public int pixelProCm(){
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getRealSize(size);

    if (displayData | im_feeling_lucky)
        displayData();


    double y = size.y/metrics.ydpi*2.54;
    double pxprocm = size.y/y;

    return (int)pxprocm;
}


@SuppressLint("SetTextI18n")
private void initialize(boolean keepScore){
    Bitmap o24Map = BitmapFactory.decodeResource(getResources(), R.drawable.o24);
    Bitmap o16Map = BitmapFactory.decodeResource(getResources(), R.drawable.o16);
    Bitmap o9Map = BitmapFactory.decodeResource(getResources(), R.drawable.o9);

    rasterO24 = rasterizeImage (o24Map);
    rasterO16 = rasterizeImage (o16Map);
    rasterO9 = rasterizeImage (o9Map);
    //get TouchInput and initialize its fields with 1st O
    Toolbar toolbar = view.findViewById(R.id.toolbar);



    ((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
    Objects.requireNonNull(((AppCompatActivity)getActivity()).getSupportActionBar()).setDisplayShowTitleEnabled(false);
    if (!keepScore) {
        if (touch != null) {
            if (touch.exerciseStarted) {
                touch.exerciseStarted = false;
                countDownTimer.cancel();
            }
        }
        score = 0;
    }



   // Problem here

    touch = view.findViewById(R.id.touchInput_fragment);
    touch.activity = this;
    touch.images = images;
    touch.activeOItem = images.get(0);
    touch.activeOItemIndex = 0;
    touch.o24Map = o24Map;
    touch.rasterO24 = rasterO24;
    touch.timer = true;
    images = new ArrayList<>();
    blanks = new ArrayList<>();
    points = view.findViewById(R.id.pointsDisplay);
    points.setText(String.format(getResources().getString(R.string.points), lastScore));
    time = view.findViewById(R.id.timeDisplay);
    time.setText(String.format(getResources().getString(R.string.time) ,  60));
    if (!keepScore) {
        int start = 60000;
        if (tenSecTimer) {
            start = 10000;
            time.setText(String.format(getResources().getString(R.string.time) , 10));
        }
        countDownTimer = new CountDownTimer(start, 1000) {
            public void onTick(long millisUntilFinished) {
                TextView time = view.findViewById(R.id.timeDisplay);
                time.setText(String.format(getResources().getString(R.string.time), (millisUntilFinished / 1000)));
                double time_delta = (System.currentTimeMillis() - touch.time_of_last_touch_event)/1000;
                if (time_delta >= 3 && time_delta < 5 && touch.activeOItemIndex % columnnumber == 0){
                    mqtt.publish("userInactivity","3");
                    hint_sent = true;
                }
                else if (time_delta >= 5 && time_delta <15 && escalation_level == 0){
                    mqtt.publish("userInactivity","5");
                    escalation_level++;
                }
                else if (time_delta >= 15 && time_delta <25 && escalation_level == 1){
                    mqtt.publish("userInactivity","15");
                    escalation_level++;
                }
                else if (time_delta >=25 && escalation_level == 2){
                    mqtt.publish("userInactivity","25");
                    escalation_level++;
                }
            }

            @RequiresApi(api = Build.VERSION_CODES.N)
            public void onFinish() {
                exercise_counter++;
                escalation_level = 0;
                TextView time = view.findViewById(R.id.timeDisplay);
                time.setText(getResources().getString(R.string.TimeIsUp));
                lastScore = score;
                ((TextView)view.findViewById(R.id.notificationText)).setText(String.format(getResources().getString(R.string.PointsNotificationText) ,lastScore));
                view.findViewById(R.id.oTable).setAlpha(0.25f);
                view.findViewById(R.id.notification).setVisibility(View.VISIBLE);

                touch.timer = false;


                String message = "" + score;
                mqtt.publish(topic, message);

            }
        };
    }
    else {
        touch.exerciseStarted = true;
    }
    touch.pixelProCm = pxpcm;
}

//generates the Grid with the "O"s
public void generateGrid(){

    //gets the size of the Display in px
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getRealSize(size);

    getActivity().setContentView(R.layout.fragment_o_strike_through);

    TableLayout oTable = view.findViewById(R.id.oTable);


    double scalingFactor = 0.95;

    //calculates the number of Os that can be placed on the screen width
    columnnumber = size.x /(int)(pxpcm*scalingFactor*7/5)-1;

    //calculates the number of Os that can be placed on the screen height
    rownumber = (int)(size.y - (100 * getResources().getDisplayMetrics().density));
    rownumber = (int)(rownumber/(pxpcm*scalingFactor)/2);

    if (generateGrid | im_feeling_lucky){
        System.out.println("Anzahl O-Reihen: " + columnnumber);
        System.out.println("Anzahl O-Spalten: " + rownumber);
    }

    int count = 0;
    for (int i = 0; i < rownumber; i++){
        TableRow tR = new TableRow (getContext());
        tR.setGravity(Gravity.CENTER);
        ArrayList<ImageView> tempO = new ArrayList<>();
        for (int j = 0; j < columnnumber; j++){
            // add O-images to table rows
            ImageView img = new ImageView(getContext());
            img.setAdjustViewBounds(true);
            img.setMaxHeight((int)(pxpcm * scalingFactor));
            setOImage(img, count);
            tR.addView(img);
            img.setId(count);

            if(i%2 == 0)
                images.add(img);
            else
                tempO.add(img);
            //images.add(img);

            // add spacing between each O
            if (j < (columnnumber -1)) {
                ImageView spacing = new ImageView(getContext());
                spacing.setImageResource(R.drawable.blank_between_o);
                spacing.setAdjustViewBounds(true);
                spacing.setMaxHeight((int) (pxpcm * scalingFactor));
                tR.addView(spacing);
            }
            count++;
        }
        if(i%2 == 1){
            Collections.reverse(tempO);
            images.addAll(tempO);
        }
        oTable.addView(tR, 2*i);

   
        TableRow tRBlank = new TableRow(getContext());

        tRBlank.setGravity(Gravity.CENTER);
        ArrayList<ImageView> tempBlanks = new ArrayList<>();
        for (int j = 0; j < columnnumber; j++){
            // add Blanks to table rows
            ImageView blankImg = new ImageView(getContext());
            blankImg.setAdjustViewBounds(true);
            blankImg.setMaxHeight((int)(pxpcm * scalingFactor));
            blankImg.setImageResource(R.drawable.blank_line);

            if(i%2 == 0)
                blanks.add(blankImg);
            else
                tempBlanks.add(blankImg);


            tRBlank.addView(blankImg);

        }


        if(i%2 == 1){
            Collections.reverse(tempBlanks);
            blanks.addAll(tempBlanks);
        }
        oTable.addView(tRBlank, (2*i)+1);
    }

    if(lastScore > 0) {
        blanks.get((lastScore - 1)%(rownumber*columnnumber)).setImageResource(R.drawable.arrow_up);
    }
}



public void setClickListener(){
    Button button = view.findViewById(R.id.notificationButton);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            View notification = (View) v.getParent();
            notification.setVisibility(View.INVISIBLE);
            view.findViewById(R.id.oTable).setAlpha(1f);
            if (exercise_counter < exercise_repetition_number) {
                reset();
            }
            else if (exercise_counter == exercise_repetition_number ){
                view.findViewById(R.id.oTable).setAlpha(0.25f);
                ((TextView)view.findViewById(R.id.notificationText)).setText(getResources().getString(R.string.exerciseFinished));
                notification.setVisibility(View.VISIBLE);
                exercise_counter++;
            }
            else if (exercise_counter > exercise_repetition_number){
               // returnToMainMenu();

            }

        }
    });
}


public class TouchInput_Fragment extends View{


    boolean im_feeling_lucky        = true;

    boolean onSizeChanged           = false;
    boolean TouchInput              = false;
    boolean onDraw                  = false;
    boolean onTouchEvent            = false;
    boolean validation              = false;
    boolean validateLineStartEnd    = false;
    boolean isValidMove             = false;
    boolean getResizedBitmap        = false;


    private final Paint line, background;
    private Canvas c;
    private Canvas screenCan;
    private Path touchPath;
    private Bitmap b;
    private Bitmap screenBit;
    int screenbar = 94;

    ArrayList<ImageView> images = new ArrayList<>();
    RectF boundsOfPath = new RectF();
    ImageView activeOItem;
    int activeOItemIndex;
    Bitmap lineBitmapOriginal;
    Bitmap lineBitmapScaledUp;
    Bitmap o24Map;
    int[][] rasterO24;
    int[][] rasterLine;
    TextView points;
    boolean exerciseStarted = false;
    OStrikeThroughFragment activity;
    int pixelProCm;
    boolean from_left_to_right = true;
    int os_completed_in_row = 0;
 
    double minDiff = 0.3;
    double maxDiff = 1.5;
    boolean timer;
    int downx = 0;
    int downy = 0;
    double time_of_last_touch_event;


    @Override
    protected void onSizeChanged(int width, int height, int oldwidth, int oldheight) {
        super.onSizeChanged(width, height, oldwidth, oldheight);
        b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        screenBit = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        c = new Canvas(b);
        screenCan = new Canvas(screenBit);
    }


    public TouchInput_Fragment(Context context) {
        this(context, null);
    }

    public TouchInput_Fragment(Context context, AttributeSet attrs) {
        super(context, attrs);

        line = new Paint(Paint.ANTI_ALIAS_FLAG);
        line.setStyle(Paint.Style.STROKE);
        line.setColor(Color.BLUE);
        line.setStrokeWidth((float)(pixelProCm * 0.04));

        background = new Paint(Paint.ANTI_ALIAS_FLAG);
        background.setColor(Color.WHITE);

        touchPath = new Path();
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(b, 0, 0, background);
        canvas.drawBitmap(screenBit, 0, 0, background);
        canvas.drawPath(touchPath, line);

    }

    int count_drawn_lines;
    int count_drawn_success;
    int max_tries;
    int max_tries_tmp;

    @SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        time_of_last_touch_event = System.currentTimeMillis();

        activity.escalation_level = 0;
        activity.hint_sent = false;
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchPath.moveTo(touchX, touchY);
                downx = (int)touchX;
                downy = (int)touchY;
                if ((onTouchEvent) | (im_feeling_lucky))
                    System.out.println("Neues Touchevent:");
                count_drawn_lines++;
                invalidate();
                break;

            case MotionEvent.ACTION_MOVE:
                touchPath.lineTo(touchX, touchY);
                if ((onTouchEvent) | (im_feeling_lucky))
                    System.out.println("Koordinaten:   X = " + touchX + "   Y = " + touchY);
                invalidate();
                break;

            case MotionEvent.ACTION_UP:
                touchPath.lineTo(touchX, touchY);
                int upx = (int)touchX;
                int upy = (int)touchY;
                c.drawPath(touchPath, line);
                screenCan.drawPath(touchPath, line);

          
                int[] screenCoordsTouch = new int[2];
                this.getLocationOnScreen(screenCoordsTouch);

                //get Bitmap from drawn Line covering ActiveO
                int [] location = new int [2];
                activeOItem.getLocationOnScreen(location);
                lineBitmapOriginal = Bitmap.createBitmap(b, activeOItem.getLeft(), location[1]-screenCoordsTouch[1], activeOItem.getWidth(), activeOItem.getHeight());

             
                lineBitmapScaledUp = getResizedBitmap(lineBitmapOriginal, o24Map.getWidth(), o24Map.getHeight());

                //Rasterizes the scaled Bitmap
                rasterLine = OStrikeThroughActivity.rasterizeLine(lineBitmapScaledUp, 0);

                //calls a function that prints out some debug-stuff
                if (onTouchEvent | im_feeling_lucky)
                    debugPrints(location[1], screenCoordsTouch[0], screenCoordsTouch[1]);

                //get Rectangle from drawn Line
                touchPath.computeBounds(boundsOfPath,true);

                //Starts validation if the timer is still running
                validateLine(upx, upy);

                break;
        }
        return true;
    }


    private void validateLine(int upx, int upy){
        max_tries_tmp++;
        boolean startEndOK = false;
        boolean lineOK = false;
        if (timer) {
            //Check, if the line starts and ends in a certain area around the O
            startEndOK = validateLineStartEnd(downx, downy, upx, upy);
            if (validation | im_feeling_lucky)
                System.out.println("Linie innerhalb:" + startEndOK);

          
            lineOK = isValidMove(rasterLine, ((int)images.get(activeOItemIndex).getId() % 156));
            if (validation | im_feeling_lucky)
                System.out.println("Linie durch O (Top --> Down):" + lineOK);

     
            if (!lineOK) {
                rasterLine = OStrikeThroughActivity.rasterizeLine(lineBitmapScaledUp, 1);
                lineOK = isValidMove(rasterLine, activeOItemIndex);
                if (validation | im_feeling_lucky)
                    System.out.println("Linie durch O (Left --> Right):" + lineOK);
            }

            if (startEndOK && lineOK) {
                activeOItem.setBackgroundColor(Color.GREEN);

                activeOItemIndex++;
                activity.score++;
                activity.points.setText(String.format(getResources().getString(R.string.points), activity.score));
                if (activeOItemIndex >= 0 && activeOItemIndex < images.size()) {
                    activeOItem = images.get(activeOItemIndex);
                } else {
                    activity.resetKeepScore(from_left_to_right);
                }
                count_drawn_success++;
                if(max_tries < max_tries_tmp){
                    max_tries = max_tries_tmp;
                }
                max_tries_tmp = 0;
            } else {
                activeOItem.setBackgroundColor(Color.RED);
            }
        }

        if (!exerciseStarted){
            activity.mqtt.publish("pepper","noPatientData");
            activity.mqtt.publish("pepper","exerciseStarted" + String.valueOf(activity.exercise_counter+1));
            activity.countDownTimer.start();
            exerciseStarted = true;
        }

        touchPath = new Path();
        if (TouchInput | im_feeling_lucky)
            System.out.println("Touchevent beendet");
        invalidate();

        c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
    }

    private boolean isValidMove(int[][] rasterLine, int index){
        double offset = 0.3;
        int [][] rasterO = activity.rasterO24;
        if (activity.mode == 1){
            int varying_OIndex = activity.varying_OArray[index];
            switch (varying_OIndex) {
                case 1:
                    rasterO = activity.rasterO9;
                    offset = 0.1;
                    break;
                case 2:
                    rasterO = activity.rasterO16;
                    offset = 0.2;
                    break;
                default:
                    rasterO = activity.rasterO24;
                    offset = 0.3;
            }
        }
        boolean returnValue = false;

        int countO = 0, countUnder = 0, countOver = 0;
        double prozent = 0.01;

        int width = rasterLine.length;
        int height = rasterLine[0].length;

        int initialPlusX = 0;
        int initialPlusY = 0;
        double diff;
        double mindistance = offset * pixelProCm * (o24Map.getWidth() / (double)activeOItem.getWidth());
        boolean touchO = false;


}

}

fragment_o_strike_through.xml

     <androidx.constraintlayout.widget.ConstraintLayout 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"
     tools:context=".pepperstrike.OStrikeThroughFragment"
      >

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:clickable="true"
android:focusable="true"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:layout_editor_absoluteX="16dp"
    tools:layout_editor_absoluteY="12dp">

    <TextView
        android:id="@+id/timeDisplay"
        android:layout_width="26dp"
        android:layout_height="45dp"
        android:layout_weight="1"
        android:text="@string/time"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />

    <TextView
        android:id="@+id/pointsDisplay"
        android:layout_width="38dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/points"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>


<TableLayout
android:id="@+id/oTable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:baselineAligned="false"
android:gravity="center_horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar" />

<com.example.metaapptablet.pepperstrike.TouchInput_Fragment

android:id="@+id/touchInput_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
tools:context=".pepperstrike.OStrikeThroughFragment"
tools:layout_editor_absoluteX="4dp" />

<LinearLayout
android:id="@+id/notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="100dp"
android:layout_marginTop="200dp"
android:layout_marginEnd="100dp"
android:layout_marginBottom="200dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<TextView
    android:id="@+id/notificationText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_weight="2"
    android:fontFamily="sans-serif"
    android:lineSpacingExtra="14sp"
    android:text="@string/PointsNotificationText"
    android:textAlignment="center"
    android:textColor="@android:color/black"
    android:textSize="36sp"
    android:typeface="normal" />

    <Button
    android:id="@+id/notificationButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:layout_weight="3"
    android:backgroundTint="#2196F3"
    android:fontFamily="sans-serif"
    android:text="@string/close"
    android:textAlignment="center"
    android:textColor="@android:color/black"
    android:textSize="36sp"
    android:typeface="normal" />
    </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

Leave a Comment