How to implement a start/stop "button" in Android - java

My goal is to have a CardView that when is clicked, it goes from Start -> Stop and vice versa when clicked again. Inside the CardView I have two TextView which I would like to alter when it's clicked. The functionality behind this, would be to start a foreground service and stop it accordingly.
What I have in mind for the layout xml:
<GridLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="#+id/cardStartStop">
<TextView
android:id="#+id/txtCardStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/card_start"
app:drawableTopCompat="#drawable/ic_start_black_24dp" />
<TextView
android:id="#+id/txtCardStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:text="#string/card_stop"
app:drawableTopCompat="#drawable/ic_stop_circle_black_24dp" />
</androidx.cardview.widget.CardView>
</GridLayout>
Then I thought to programmatically change the visibility of each TextView and persist its state using SharedPreferences when closing and re-opening app. My question is more at a design level, is there a better way to achieve this or I'm pointing in the right direction?

Add one TextView and setOnClickListener
XML File
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Start"
android:id="#+id/text_start_stop"
/>
</androidx.cardview.widget.CardView>
Class
private TextView tStartStop;
Boolean flag = true;
ClickEvent
tStartStop = findViewById(R.id.text_start_stop);
tStartStop.setOnClickListener(view -> {
if (flag) {
flag = false;
tStartStop.setText("Start");
} else {
flag = true;
tStartStop.setText("Stop");
}
});

Related

setBackgroundColor is crashing the android application

I recently made a small app that should change the background color & text of the application when a certain amount of money is generated (here 100000). However, whenever I go past 10000, the application crashes. I am not sure why and can not get around it. I saw that this problem is with background color only because it is otherwise displaying text correctly.
Here is the XML for activity_main
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/Trial"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#EC5353"
tools:context=".MainActivity">
<TextView
android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="92dp"
android:gravity="center"
android:text="#string/Title"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="72dp"
android:text="#string/moneyPresent"
android:textSize="22sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/Title" />
<Button
android:id="#+id/moneyGenerator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="72dp"
android:background="#FFFFFF"
android:backgroundTint="#732424"
android:backgroundTintMode="multiply"
android:text="#string/generateMoneyButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/money" />
<TextView
android:id="#+id/richTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="#string/grind_boi"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/moneyGenerator" />
</androidx.constraintlayout.widget.ConstraintLayout>
Here is my Java Code (Omitted the packages as it would take a lot of space. Do tell me if anyone wants to read it.)
public class MainActivity extends AppCompatActivity {
private Button makeMoney;
private int totalMoney=0;
private TextView moneyText;
private TextView richAlert;
private ConstraintLayout background;
NumberFormat currency=NumberFormat.getCurrencyInstance(new Locale("en","in"));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
makeMoney = findViewById(R.id.moneyGenerator);
moneyText=findViewById(R.id.money);
richAlert=findViewById(R.id.richTag);
makeMoney.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
totalMoney+=1000;
moneyText.setText(currency.format(totalMoney));
Log.d("MoneyTag", "Money Made: "+totalMoney);
Toast.makeText(getApplicationContext(),"Total Money= \u20B9"+totalMoney,Toast.LENGTH_LONG)
.show();
if(totalMoney>=10000) {
richAlert.setText("Welcome to moneyland bro 😁");
background.setBackgroundColor(16776960);
}
}
});
}
}
makeMoney = findViewById(R.id.moneyGenerator);
moneyText=findViewById(R.id.money);
richAlert=findViewById(R.id.richTag);
You're finding all the views, except background(ConstraintLayout), that's why it is throwing NullPointerException (Most likely, because you haven't attached logs).
You need to find the layout first
background = findViewById(R.id.Trial);
in onCreate.
you haven't defined "background" view in the above.
to use .setBackgroundColor you need to use it with some view
try making object of layout view then change the color of that layout
mConstraintLayout =
(ConstraintLayout)findViewById(R.id.Trial);
makeMoney = findViewById(R.id.moneyGenerator);
moneyText=findViewById(R.id.money);
richAlert=findViewById(R.id.richTag);
if(totalMoney>=10000) {
richAlert.setText("Welcome to moneyland bro 😁");
mConstraintLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.yellow));
background = findViewById(R.id.Trial);
just find layout and null pointer excpetion will removed

onClick method not working in android studio

I made a side navigation drawer and it works fine but whenever I click any option in navigation drawer nothing happens.It's like it is not taking any input. Onclicking any option I want to redirect user to a new activity but unfortunately it doesn't happens.
XML code is as follows
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
android:clickable="true"
android:onClick="ClickTournament_info"
android:focusable="true">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Tournament Info"
android:padding="12dp"
android:layout_marginStart="16dp"/>
<ImageView
android:layout_marginTop="-10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="48dp"
android:src="#drawable/tournament_info"/>
</LinearLayout>
Java code is as follows
public void ClickTournament_info(View view){
redirectActivity(this,TournamentInfo.class);
}
public static void redirectActivity(Activity activity,Class aClass) {
//Initialize intent
Intent intent = new Intent(activity,aClass);
//set flag
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//start activity
activity.startActivity(intent);
}
I think you need to use the onNavigationItemSelected method when you want to handle click events on the navigation drawer.
Learn more: https://developer.android.com/reference/com/google/android/material/navigation/NavigationView.OnNavigationItemSelectedListener#onNavigationItemSelected(android.view.MenuItem)
Firstly, try to always create an Onclicklistener instead of adding an onclick attribute in xml.
In your xml, add an ID attribute to your linear layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearlayout"
android:orientation="horizontal"
android:gravity="center_vertical"
android:clickable="true"
android:onClick="ClickTournament_info"
android:focusable="true">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Tournament Info"
android:padding="12dp"
android:layout_marginStart="16dp"/>
<ImageView
android:layout_marginTop="-10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="48dp"
android:src="#drawable/tournament_info"/>
</LinearLayout>
Now in your classfile inside the Oncreate Method,
LinearLayout LinearLayout = (LinearLayout )findViewById(R.id.linearlayout);
LinearLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
redirectActivity(this,TournamentInfo.class);
}
});
You already have an onClick method. start navigating from that method only.
Try like this,

Avoid clicking of full layout

I only want my textview with id clickable_txtView to be clickable in relative layout. Here is the code -
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#android:id/empty"
android:clickable="false">
<ImageView
android:layout_width="120sp"
android:layout_height="130sp"
android:layout_centerHorizontal="true"
android:src="#drawable/flower"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="120sp"
android:text="Dont click me />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/clickable_txtView"
android:gravity="center"
android:paddingTop="140sp"
android:clickable="true"
android:text="Click me" />
</RelativeLayout>
#OnClick(R.id.clickable_txtView)
public void txtViewClick() {
//Some event
}
Thr problem is I am able to click whole relative layout and some event happens after onclicking relative layout.
How do I avoid this and make it limited to text view only.
Your textview has an attribute android:paddingTop="140sp" which basically wraps over the entire relative layout, because of which you are having the problem with onClick behaviour.
Use this RelativeLayout structure (provide ID to the "don't click me" textview, and place the "clickable textview" below it.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<ImageView
android:layout_width="120sp"
android:layout_height="130sp"
android:layout_centerHorizontal="true"
android:src="#mipmap/ic_launcher"
android:layout_alignParentTop="true"
/>
<TextView
android:id="#+id/do_not_click"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingTop="120sp"
android:enabled="false"
android:text="Dont click me" />
<TextView
android:id="#+id/clickable_txtView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:gravity="center"
android:layout_below="#id/do_not_click"
android:text="Click me" />
</RelativeLayout>
In your activity where you are inflating this view try this:
first initialize your textview
TextView textView = (TextView) findViewById(R.id.clickable_txtView);
then apply clickListner on it
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do your work here
}
});
I'm not sure but you can try adding below line to your parent layout
android:touchscreenBlocksFocus="true"
like
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#android:id/empty"
android:touchscreenBlocksFocus="true">

how to collapse all previous nested view when onclick current view in android

my layout code is below
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/invitation_single"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="?android:dividerVertical"
android:dividerPadding="5dp"
android:showDividers="middle"
tools:context=".MainActivity">
<ImageButton
android:id="#+id/image"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#drawable/ic_action_event" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:clickable="false"
android:focusable="true"
android:orientation="vertical">
<TextView
android:id="#+id/invitation_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="0dp"
android:paddingTop="3dp"
android:textColor="#color/black"
android:textSize="18sp" />
<TextView
android:id="#+id/invitation_place"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="0dp"
android:textColor="#color/black"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:id="#+id/hidden"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginLeft="-270dp"
android:layout_marginTop="60dp"
android:layout_weight="1"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal"
android:paddingTop="1dp"
android:visibility="gone"
android:weightSum="3">
<Button
android:id="#+id/yesbutton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="7dp"
android:layout_weight="1"
android:background="#color/blue"
android:text="Yes"
android:textColor="#color/black"></Button>
<Button
android:id="#+id/nobutton"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="25dp"
android:layout_weight="1"
android:background="#color/blue"
android:text="No"
android:textColor="#color/black"></Button>
<Button
android:id="#+id/buttonmaybe"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="#color/blue"
android:text="Maybe"
android:textColor="#color/black"></Button>
</LinearLayout>
In above code "invitation_single" is root layout and "hidden" is nested layout.
my programming code is below
final LinearLayout first = (LinearLayout) convertView.findViewById(R.id.invitation_single);
final LinearLayout second = (LinearLayout) convertView.findViewById(R.id.hidden);
first.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.invitation_single:
second.setVisibility(second.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
break;
}
}
});
My root layout(invitation_single) have two "textviewes" and nested layout(hidden) have three "buttons".When i am on tap my root layout the nested layout visible immediately below the root layout.In my output i have two events when i am on tap first event the nested layout(buttons) visible similarly if i am on click second event i need to hide the nested layout of previous event and show the nested layout of current event(that means i need to visible the nested layout of current event and close all other nested layouts).how can i achieve this help me.
Playing with View.GONE and View.VISIBLE is tricky. When the view is gone, it does not simply come back, it can mess up everything. One simple solution to get it back is to re-call setContentView after changing from View.GONE to View.VISIBLE. Make sure you save the contents of your views before calling setContentView and then refresh them with the saved values after calling setContentView.
Some people choose to call onCreate(null) which also does the job. In both case you need to save and restore the contents of your views.
Another alternative is to use LayoutInflater.
Example (not tested)
first.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.invitation_single:
if(second.getVisibility() == View.VISIBLE){
second.setVisibility(View.GONE);
}else{
// save the content of your views
setContentView(....); // call as you called in onCreate or whatever
// restaure the content of your views.
}
break;
}
}
});

Trouble identifying the type of widget to expand/collapse an area

Consider the widget hello:
When clicked, it opens the area at the bottom with additional widgets (text, buttons, etcetera):
What is this kind of expand/collapse widget called?
One way to do this is to build your whole layout with the text and the buttons, but hide them initially by setting their visibility to gone or invisible. Then in code in the onClick listener of the "hello_text" text view, you can change their visibility to visible.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/hello_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello_text" />
<TextView
android:id="#+id/the_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/my_text"
android:visibility="invisible" />
<LinearLayout android:id="#+id/btn_holder"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="invisible">
<Button android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_text1" />
<Button android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_text2" />
</LinearLayout>
</LinearLayout>
Now in your activity or fragment you can do:
TextView the_text_view = (TextView) v.findViewById(R.id.the_text);
LinearLayout ll_btn_holder = (LinearLayout) v.findViewById(R.id.btn_holder);
TextView hello_text_view = (TextView) v.findViewById(R.id.hello_text);
hello_text_view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
the_text_view.setVisibility(View.VISIBLE);
ll_btn_holder.setVisibility(View.VISIBLE);
}
});

Categories

Resources