Android Timer makes ListView ignore clicks sometimes - java

I'm creating a simple little game to practice my coding but I've stumbled into a problem. It's not game breaking but it's certainly annoying. In my game, I have a class Tappable which is what my ListView is populated with. Every time you tap on a ListView element, my OnItemClickListener just adds 1 to the amount you have of a Tappable.
Long story short, I use a custom ArrayAdapter and I have AsyncTask running on a loop with handlers in order to calculate how much money you are making. This implementation of a timed AsyncTask was done so I could put calculations on another thread and then update the UI onPostExecute. However, when I tap on a ListView element, some taps are completely ignored. This happens more severely the lower the interval is between the timed AsyncTasks.
Here is my MainActivity.java
import android.os.AsyncTask;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
TextView moneyView;
ListView tappablesView;
ArrayList<Tappable> tappables = new ArrayList<>();
TappableAdapter tappableAdapter;
double money = 0; // Total amount of money you have
double time; // Var to do checks on the amount of time to finish AsyncTask
// Here is the stuff that I use as my Timer.
int millisecondsToDelay = 30;
Handler handler = new Handler();
public class WorldUpdater extends AsyncTask<Void, Integer, Double> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//This is for checking how long it takes my Tasks to complete
time = System.currentTimeMillis();
}
#Override
protected Double doInBackground(Void... params) {
// Var to hold amount to add to money
double moneyAddable = 0;
// Go through the tappables arraylist
for (int i = 0; i < tappables.size(); i++) {
Tappable t = tappables.get(i);
// increase the progress to a payout for a tappable
if (t.getAmount() > 0) {
t.updateProgress();
}
// add any money that can be collected to moneyAddable
moneyAddable += t.collectMoney();
}
// To be processed in onPostExecute
return moneyAddable;
}
#Override
protected void onPostExecute(Double m) {
super.onPostExecute(m);
// add the moneyAddable from doInBackground to the amount of money you have
money += m;
// Set the moneyView text to show how much money you have
updateMoneyView();
// Tappable progress increased, so show that in the list view
tappableAdapter.notifyDataSetChanged();
// Now we see how long the task took
time = System.currentTimeMillis() - time;
// If the task took longer than the amount I want it to delay, then say how long it took
if (time > millisecondsToDelay) {
Log.i("Timer info", "Too long: " + time);
}
handler.postDelayed(new Runnable() {
#Override
public void run() {
new WorldUpdater().execute();
}
}, (((long) (millisecondsToDelay - time)) > 0)? (long) (millisecondsToDelay - time): (long) 0);
}
}
public void updateMoneyView() {
moneyView.setText(String.format(Locale.getDefault(), "$%,.2f", money));
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
moneyView = (TextView) findViewById(R.id.Money);
tappablesView = (ListView) findViewById(R.id.TappablesView);
// The two tappables in the listview
tappables.add(new Tappable("Buy me!", .25, 1, 1500));
tappables.add(new Tappable("Buy me as well!", 1, 2.25, 1000));
tappableAdapter = new TappableAdapter(this, tappables);
tappablesView.setAdapter(tappableAdapter);
tappablesView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// On item click, increase the amount of the tappable that was clicked by 1
tappables.get(position).buyAmount(1);
}
});
updateMoneyView();
// Start my timer
handler.postDelayed(new Runnable() {
#Override
public void run() {
new WorldUpdater().execute();
}
}, millisecondsToDelay);
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
}
}
Here is my Tappable.java
public class Tappable {
private String title;
private double revenue, cost, revenuePerItem, costPerItem;
private int progress, progressNeeded, progressStep, amount;
private boolean canCollect = false;
private double amountToCollect = 0;
public Tappable(String title, double r, double c, int ps) {
this.title = title;
revenuePerItem = r;
amount = 0;
revenue = revenuePerItem * amount;
costPerItem = c;
cost = costPerItem * (amount + 1);
progressNeeded = 100000;
progress = 0;
progressStep = ps;
}
public void buyAmount(int n) {
amount += n;
updateCost();
updateRevenue();
}
public void updateProgress() {
progress += progressStep;
if (progress >= progressNeeded) {
progress = 0;
amountToCollect += getRevenue();
canCollect = true;
}
}
public double collectMoney() {
double amountCollectable = 0;
if (canCollect) {
amountCollectable = amountToCollect;
amountToCollect = 0;
canCollect = false;
}
return amountCollectable;
}
public void updateCost() {
cost = costPerItem * (amount + 1);
}
public void updateRevenue() {
revenue = revenuePerItem * amount;
}
public String getTitle() {
return title;
}
public int getAmount() {
return amount;
}
public double getCost() {
return cost;
}
public int getProgress() {
return progress;
}
public int getProgressNeeded() {
return progressNeeded;
}
public double getRevenue() {
return revenue;
}
}
Here is my TappableAdapter.java
import android.app.Activity;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Locale;
public class TappableAdapter extends BaseAdapter {
private final Activity context;
private final ArrayList<Tappable> tappables;
private final Resources res;
private final LayoutInflater inflater;
public TappableAdapter(Activity context, ArrayList<Tappable> t) {
this.context = context;
tappables = t;
res = context.getResources();
inflater = context.getLayoutInflater();
}
#Override
public int getCount() {
return tappables.size();
}
#Override
public Object getItem(int position) {
return tappables.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Tappable t = tappables.get(position);
View rowView = inflater.inflate(R.layout.list_item, null, true);
TextView titleView, amountView, costView, revenueView;
titleView = (TextView) rowView.findViewById(R.id.Title);
amountView = (TextView) rowView.findViewById(R.id.Amount);
costView = (TextView) rowView.findViewById(R.id.Cost);
revenueView = (TextView) rowView.findViewById(R.id.Revenue);
ProgressBar p = (ProgressBar) rowView.findViewById(R.id.progressBar);
titleView.setText(t.getTitle());
amountView.setText("Amount: " + t.getAmount());
costView.setText(String.format(Locale.getDefault(), "$%,.2f", t.getCost()));
revenueView.setText(String.format(Locale.getDefault(), "$%,.2f", t.getRevenue()));
p.setMax(t.getProgressNeeded());
p.setProgress(t.getProgress());
return rowView;
}
}
Here is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.jake.mypointclicker.MainActivity">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="Simple Point Clicker"
android:textColor="#android:color/background_light"
android:textSize="36sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintVertical_weight="0" />
<TextView
android:id="#+id/Money"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="$123,456,789.00"
android:textColor="#android:color/holo_orange_dark"
android:textSize="30sp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView"
android:layout_marginEnd="8dp"
app:layout_constraintVertical_weight="0" />
<Button
android:id="#+id/button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:text="Button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/Money"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintVertical_weight="0" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button"
app:layout_constraintVertical_weight="0">
<ListView
android:id="#+id/TappablesView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Here is my list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:orientation="vertical"
android:padding="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top|left"
android:text="Test Title"
android:textColor="#android:color/holo_blue_light"
android:textSize="20sp" />
<TextView
android:id="#+id/Revenue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top|right"
android:text="$123,456,789.00"
android:textColor="#android:color/holo_green_light"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/Amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top|left"
android:text="Amount: 123456789" />
<TextView
android:id="#+id/Cost"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="top|right"
android:text="$123,456,789.00"
android:textColor="#android:color/holo_red_light"
android:textSize="20sp" />
</LinearLayout>
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
I have tried many ways of doing my timer. I tried just using Timer with a timertask which had the same effect. Line 25 or so is where my variable for how long to delay is. Lowering that increases the amount of clicks that are ignored. Raising it has the inverse effect but makes the progress bars look less smooth. Like I said, it's not a game braking problem, but I don't understand why the onItemClick is not called sometimes when I try updating the UI frequently. Is the Listener itself on the UI thread and it is being blocked when I update the UI in my AsyncTask?

Related

Unable to add more than one item in a listview

I am working on a tasks app, for which I created a list view that shows list items consitsting of task names, their priority etc. The data given to the list view is from an sqlite database. I, however, am unable to add more than one item to the list. I have no idea why. I have created a method to do so, but it doesn't seem to work. I don't know if the error is due to the database or my method itself. Even debugging didn't help. Please note that I am using a list adapter since I am using a custom listview.
Code for Activity where list is shown :
package com.example.taskmasterv3;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
public class TaskSummary extends AppCompatActivity {
ListView lvTaskList;
TextView tvBreak, tvBreakAfterEvery, txt1, txt2, text1, hmm;
TextView break_duration_mins;
ArrayList<SubtaskPartTwo> subtaskList = new ArrayList<>();
String subtname;
String pri;
String time;
DBHelper dbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_summary);
lvTaskList = findViewById(R.id.lvTaskList);
tvBreak = findViewById(R.id.tvBreak);
tvBreakAfterEvery = findViewById(R.id.tvBreakAfterEvery);
txt1 = findViewById(R.id.txt1);
txt2 = findViewById(R.id.txt2);
break_duration_mins = findViewById(R.id.break_duration_mins);
text1 = findViewById(R.id.text1);
hmm = findViewById(R.id.hmm);
dbHelper = new DBHelper(this);
subtname = getIntent().getStringExtra("subtaskname");
pri = getIntent().getStringExtra("pri");
time = getIntent().getStringExtra("time");
// Using adapter for listview :
SubtaskDetailAdapter adapter = new SubtaskDetailAdapter(this, subtaskList);
lvTaskList.setAdapter(adapter);
SubtaskPartTwo subtaskPartTwo = new SubtaskPartTwo(subtname, pri, time);
subtaskList.add(subtaskPartTwo);
adapter.addANewSubTask(subtaskPartTwo);
double working_hours = getIntent().getIntExtra("working_hours", 1);
double working_minutes = getIntent().getIntExtra("working_minutes", 0);
double without_break_hours = getIntent().getIntExtra("without_break_hours", 1);
double without_break_minutes = getIntent().getIntExtra("without_break_minutes", 0);
double break_duration = getIntent().getIntExtra("break_duration", 20);
String a = working_hours + " h";
txt1.setText(a);
String b = working_minutes + " m";
break_duration_mins.setText(b);
String c = break_duration + " m";
txt2.setText(c);
//Mathematics
double g = working_hours * 100;
double h = g + working_minutes;
double i = h + break_duration;
double j = i / 60;
double p = (int) j;
double q = j - p;
double r = q * 60;
without_break_hours = p;
without_break_minutes = r;
String d = without_break_hours + " h";
String e = without_break_minutes + " m";
text1.setText(d);
hmm.setText(e);
}
}
Code for Adapter Class :
package com.example.taskmasterv3;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class SubtaskDetailAdapter extends ArrayAdapter<SubtaskPartTwo> {
private final Context context;
private ArrayList<SubtaskPartTwo> values;
public boolean deleted;
public SubtaskDetailAdapter(Context context, ArrayList<SubtaskPartTwo> list) {
//since your are using custom view,pass zero and inflate the custom view by overriding getview
super(context, 0 , list);
this.context = context;
this.values = list;
}
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//check if its null, if so inflate it, else simply reuse it
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.task_summary_item, parent, false);
}
//use convertView to refer the childviews to populate it with data
TextView tvSubtaskName = convertView.findViewById(R.id.tvlolitaskname);
ImageView ivPri = convertView.findViewById(R.id.ivloliPri);
ImageView ivTime = convertView.findViewById(R.id.ivloliTime);
tvSubtaskName.setText(values.get(position).getSubtaskName());
if (values.get(position).getPri() == "h")
{
ivPri.setImageResource(R.drawable.priority_high);
}
if (values.get(position).getPri() == "m")
{
ivPri.setImageResource(R.drawable.priority_med);
}
if (values.get(position).getPri() == "l")
{
ivPri.setImageResource(R.drawable.priority_low);
}
if (values.get(position).getTime() == "more")
{
ivPri.setImageResource(R.drawable.time_symbol_more);
}
if (values.get(position).getPri() == "med")
{
ivPri.setImageResource(R.drawable.time_symbol_med);
}
if (values.get(position).getPri() == "less")
{
ivPri.setImageResource(R.drawable.time_symbol_less);
}
//return the view you inflated
return convertView;
}
//to keep adding the new subtasks try the following
public void addANewSubTask(SubtaskPartTwo newSubTask){
ArrayList<SubtaskPartTwo> newvalues = new ArrayList<>(this.values);
newvalues.add(newSubTask);
this.values = newvalues;
notifyDataSetChanged();
}
}
XML code for listview activity :
<?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/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background"
tools:context=".TaskSummary">
<!-- hello -->
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="#+id/okay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<ListView
android:id="#+id/lvTaskList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/tvBreak"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:fontFamily="#font/roboto"
android:text="Total Working Time (Including Breaks)"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
android:layout_weight="1"
android:fontFamily="#font/roboto"
android:gravity="right"
android:text="00 h"
android:textColor="#B8AEAE"
android:textSize="20sp" />
<TextView
android:id="#+id/break_duration_mins"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:gravity="left"
android:text="20 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
<!-- hello -->
<!-- hello -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/tvWorktimeWithoutBreak"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:fontFamily="#font/roboto"
android:text="Work Time Before Each Break"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="8dp"
android:layout_weight="1"
android:fontFamily="#font/roboto"
android:gravity="right"
android:text="00 h"
android:textColor="#B8AEAE"
android:textSize="20sp" />
<TextView
android:id="#+id/hmm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_weight="1"
android:gravity="left"
android:text="20 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- hello -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/tvBreakAfterEvery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:fontFamily="#font/roboto"
android:text="Break Duration"
android:textColor="#B8AEAE"
android:textSize="20sp"
app:layout_constraintBottom_toTopOf="#+id/lvTaskList"
app:layout_constraintEnd_toStartOf="#+id/lvTaskList"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:fontFamily="#font/roboto"
android:gravity="center_horizontal"
android:text="30 m"
android:textColor="#B8AEAE"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:layout_margin="16dp"
android:text="Start" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
EDIT : Database Code
package com.example.taskmasterv3;
public class TaskInfo extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_task_info);
tvTaskName = findViewById(R.id.tvTaskName);
btnProceed = findViewById(R.id.btnProceed);
dbHelper = new DBHelper(this);
tvTaskName.setVisibility(View.INVISIBLE);
if (tvTaskName.getText().equals(""))
{
tvTaskName.setClickable(false);
}
else
{
tvTaskName.setClickable(true);
}
btnSaveTaskName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tvTaskName.setVisibility(View.VISIBLE);
tvTaskName.setText(etTaskName.getText().toString().toUpperCase().trim());
etTaskName.setVisibility(View.GONE);
btnSaveTaskName.setVisibility(View.GONE);
btnNewSubtask.setEnabled(true);
}
});
tvTaskName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String tasksname = tvTaskName.getText().toString().trim();
tvTaskName.setText("");
etTaskName.setVisibility(View.VISIBLE);
etTaskName.setText(tasksname);
btnSaveTaskName.setVisibility(View.VISIBLE);
}
});
btnNewSubtask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i2 = new Intent(TaskInfo.this, SubtaskActivity.class);
startActivityForResult(i2, ENTER_SUBTASK);
overridePendingTransition(R.anim.slide_in_up, R.anim.slide_out_up);
}
});
// THE DATABASE PART
btnProceed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Cursor res = dbHelper.getdata();
while(res != null && res.moveToNext()){
subtname = res.getString(0);
pri = res.getString(1);
time = res.getString(2);
}
if (etWorkingHours.getText().toString().isEmpty())
{
etWorkingHours.setText("0");
}
if (etWorkingMinutes.getText().toString().isEmpty())
{
etWorkingMinutes.setText("0");
}
if (etWorkinghrs.getText().toString().isEmpty())
{
etWorkinghrs.setText("0");
}
if (etWorkingMins.getText().toString().isEmpty())
{
etWorkingMins.setText("0");
}
int working_hours = Integer.parseInt(etWorkinghrs.getText().toString().trim());
int working_minutes = Integer.parseInt(etWorkingMins.getText().toString().trim());
int without_break_hours = Integer.parseInt(etWorkingHours.getText().toString().trim());
int without_break_minutes = Integer.parseInt(etWorkingMinutes.getText().toString().trim());
if (etWorkingHours.getText().toString().isEmpty() || etWorkingMinutes.getText().toString().isEmpty() || etWorkinghrs.getText().toString().isEmpty() || etWorkingMins.getText().toString().isEmpty())
{
Toast.makeText(TaskInfo.this, "Field cannot be empty, please try again.", Toast.LENGTH_SHORT).show();
}
else
{
if (working_hours != 0)
{
if (working_hours > without_break_hours)
{
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("priigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
startActivity(intent);
}
if (working_hours == without_break_hours){
if (working_minutes >= without_break_minutes){
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("priigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
intent.putExtra("subtaskname", subtname);
intent.putExtra("pri", pri);
intent.putExtra("time", time);
startActivity(intent);
}
if (working_minutes < without_break_minutes){
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
}
}
if (working_hours < without_break_hours){
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
}
}
if (working_hours == 0){
if (without_break_hours == 0)
{
if (working_minutes >= without_break_minutes){
int breaktime = Integer.parseInt(tvBreakTime.getText().toString());
Intent intent = new Intent(TaskInfo.this, TaskSummary.class);
intent.putExtra("working_hours", working_hours);
intent.putExtra("working_minutes", working_minutes);
intent.putExtra("without_break_hours", without_break_hours);
intent.putExtra("without_break_minutes", without_break_minutes);
intent.putExtra("break_duration", breaktime);
intent.putExtra("subtaskname", taskName);
intent.putExtra("prihigh", NpriHigh);
intent.putExtra("primed", NpriMed);
intent.putExtra("prilow", NpriLow);
intent.putExtra("timemore", NtimeMore);
intent.putExtra("timemed", NtimeMed);
intent.putExtra("timeless", NtimeLess);
startActivity(intent);
}
if (working_minutes < without_break_minutes){
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
}
}
if (without_break_hours != 0)
{
Toast.makeText(TaskInfo.this, "Invalid Time Entered", Toast.LENGTH_SHORT).show();
}
}
}
}
});
boolean delete = getIntent().getBooleanExtra("deleted", false);
if (delete){
}
}
}
}
}
The problem is that you're creating a new ArrayList while the adapter is left using the old one. That's why notifyDataSetChanged() doesn't work because the adapter's backing list has not changed.
To fix this, update the values list directly
public void addANewSubTask(SubtaskPartTwo newSubTask) {
this.values.add(newSubTask);
notifyDataSetChanged();
}
or, add() through the adapter itself.
public void addANewSubTask(SubtaskPartTwo newSubTask) {
add(newSubTask);
notifyDataSetChanged();
}
Even if I add one item, it shows 2 (both the same)
It seems you're adding the new element twice:
SubtaskPartTwo subtaskPartTwo = new SubtaskPartTwo(subtname, pri, time);
subtaskList.add(subtaskPartTwo);
adapter.addANewSubTask(subtaskPartTwo);
Just add via adapter only as it notifies as well. Check other places too for such duplicates.

How to add values by holding button in countdowntimer

I am making boxing countdown timer and to set how long round supposed to last I am using two button first "+" and second "-" my time add every 5 seconds ex "5,10,15,20,25..." but I always I have to click to add 5 second. I would like to hold button and my value will add automatically what should I do?
I hope I add every important information in my question
my code from buttons and display
public void dodawanie1(View view) {
iloscrund=iloscrund+1;
display(iloscrund);
public void odejmowanie1(View view) {
if(iloscrund>1){
iloscrund=iloscrund-1;
display(iloscrund);
}
}
private void display(int numer) {
TextView displayInteger=(TextView) findViewById(R.id.textView16);
displayInteger.setText("" + numer);
}
odejmowanie means decrease value
dodawanie means increase value
If you mean to determine between click and hold, use onTouchListener to determine hold button event.
onTouchListener
I think you should use Runnable and Handler class for do it.
this link should be useful.
Android: Implement a 1 second interval timer before calling a function
activity_auto_inc.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AutoIncActivity">
<TextView
android:id="#+id/num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="1"
android:textSize="26sp"
android:textColor="#color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/add"
android:text="add"
android:textColor="#color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/num" />
</androidx.constraintlayout.widget.ConstraintLayout>
AutoIncActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class AutoIncActivity extends AppCompatActivity implements
View.OnLongClickListener, View.OnTouchListener {
Button add;
TextView txt;
boolean isAddPressed = false;
Handler handler;
final int TIME_INTERVAL = 100;
final int STEP = 1;
#SuppressLint("ClickableViewAccessibility")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_inc);
handler = new Handler();
add = findViewById(R.id.add);
txt = findViewById(R.id.num);
add.setOnLongClickListener(this);
add.setOnTouchListener(this);
}
#Override
public boolean onLongClick(View view) {
if (view.getId() == R.id.add) {
isAddPressed = true;
handler.postDelayed(new AutoInc(), TIME_INTERVAL);
}
return false;
}
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_UP ||
motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
isAddPressed = false;
}
return false;
}
private class AutoInc implements Runnable {
#Override
public void run() {
if (isAddPressed) {
txt.setText(String.valueOf(Integer.parseInt(txt.getText().toString()) +
STEP));
handler.postDelayed(this, TIME_INTERVAL);
}
}
}
}

Creating Flashcards in Android using Fragments

I am trying to make a simple flash card program where the user selects if they want a addition, subtraction, or multiplication problem and then use a separate fragment to show the flash card. When I run the program it doesn't seem to make it to the first fragment as it just keeps loading in the emulator. What am I doing wrong?
Main Activity
package com.example.johnt.hw4;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewGroup;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainAvtivity";
private SectionsStatePageAdapter mSectionStatePagerAdapter;
private ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: Started.");
mSectionStatePagerAdapter = new SectionsStatePageAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById( R.id.list_fragment_port );
// setup the page
setupViewPager(mViewPager);
setViewPager(0);
/*
if (findViewById( R.id.list_fragment_port ) != null ) {
// create the fragment
ListFragment listFragment = new ListFragment();
// replace anything that was there before
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// replace any existing fragment
transaction.add( R.id.list_fragment_port, listFragment );
transaction.commit();
}
*/
}
private void setupViewPager(ViewPager viewPager) {
SectionsStatePageAdapter adapter = new SectionsStatePageAdapter(getSupportFragmentManager());
adapter.addFragment(new ListFragment(), "ListFragment");
adapter.addFragment(new DataFragment(), "DataFragment");
viewPager.setAdapter(adapter);
}
public void setViewPager(int fragmentNumber) {
mViewPager.setCurrentItem(fragmentNumber);
}
public void onListFragmentInteraction(int operatorIndex) {
//create a new data fragment with appropriate information
DataFragment dataFragment = DataFragment.newInstance( operatorIndex );
// replace anything that was there before
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// replace any existing fragment
transaction.replace( R.id.list_fragment_port, dataFragment );
// activate the back button
transaction.addToBackStack(null);
transaction.commit();
}
}
SectionStatePageAdapter
package com.example.johnt.hw4;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class SectionsStatePageAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public SectionsStatePageAdapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
}
ListFragment
package com.example.johnt.hw4;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class ListFragment extends Fragment {
private static final String TAG = "ListFragment";
//private OnListFragmentInteractionListener mListener;
public final static int OPERATOR_ADDITION = 1;
public final static int OPERATOR_SUBTRACTION = 2;
public final static int OPERATOR_MULTIPLICATION = 3;
private Button addition;
private Button subtraction;
private Button multiplication;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View listfrag = inflater.inflate(R.layout.fragment_list, container, false);
// deal with the buttons
addition = (Button) listfrag.findViewById( R.id.btn_addition );
subtraction = (Button) listfrag.findViewById( R.id.btn_subtraction );
multiplication = (Button) listfrag.findViewById( R.id.btn_multiplication );
addition.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonPressed( OPERATOR_ADDITION );
}
});
subtraction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonPressed( OPERATOR_SUBTRACTION );
}
});
multiplication.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onButtonPressed( OPERATOR_MULTIPLICATION );
}
});
return listfrag;
}
public void onButtonPressed( int operatorIndex ) {
((MainActivity)getActivity()).setViewPager(1);
//mListener.onListFragmentInteraction( operatorIndex );
}
/*
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
void onListFragmentInteraction( int operatorIndex );
}
*/
}
DataFragment
package com.example.johnt.hw4;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Random;
public class DataFragment extends Fragment {
private static final String TAG = "DataFragment";
private static final String ARGS_OPERATOR = "operatorIndex";
private int operatorIndex = 1;
public static DataFragment newInstance(int operatorIndex) {
DataFragment fragment = new DataFragment();
Bundle args = new Bundle();
args.putInt(ARGS_OPERATOR, operatorIndex);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflate the layout for this fragment
View datafrag = inflater.inflate(R.layout.fragment_data, container, false);
// get a link to the textview
TextView num1 = (TextView) datafrag.findViewById( R.id.tv_num1 );
TextView num2 = (TextView) datafrag.findViewById( R.id.tv_num2 );
TextView num3 = (TextView) datafrag.findViewById( R.id.tv_num3 );
TextView operator = (TextView) datafrag.findViewById( R.id.tv_operator );
Random r = new Random();
switch ( operatorIndex ) {
case ListFragment.OPERATOR_ADDITION:
int x = r.nextInt(100); // 0 - 99
int y = r.nextInt(100); // 0 - 99
int z = x + y;
num1.setText("" + x);
num2.setText(""+y);
num3.setText(""+z);
operator.setText("+");
break;
case ListFragment.OPERATOR_SUBTRACTION:
int a = r.nextInt(100); // 0 - 99
int b = r.nextInt(100 - a + 1) + a; // a - 99
int c = a - b;
num1.setText(a);
num2.setText(b);
num3.setText(c);
operator.setText("-");
break;
case ListFragment.OPERATOR_MULTIPLICATION:
int v = r.nextInt(100); // 0 - 99
int m = r.nextInt(100); // 0 - 99
int n = v * m;
num1.setText(v);
num2.setText(m);
num3.setText(n);
operator.setText("X");
break;
}
return datafrag;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/list_fragment_port"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</android.support.constraint.ConstraintLayout>
fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="#+id/btn_addition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Addition"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/btn_subtraction"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/btn_subtraction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/btn_multiplication"
android:layout_alignParentTop="true"
android:text="Subtraction"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/btn_multiplication"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_addition" />
<Button
android:id="#+id/btn_multiplication"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Multiplication"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/btn_subtraction" />
</android.support.constraint.ConstraintLayout>
fragment_data.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="#+id/tv_num1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="num1"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/tv_operator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/tv_num2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="num2"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/tv_equals"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_operator" />
<TextView
android:id="#+id/tv_num3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="num3"
android:textSize="25sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_equals" />
<TextView
android:id="#+id/tv_operator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="operator"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/tv_num2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_num1" />
<TextView
android:id="#+id/tv_equals"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="="
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="#+id/tv_num3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/tv_num2" />
</android.support.constraint.ConstraintLayout>

Error: android.widget.LinearLayout cannot be cast to android.widget.ImageView

There was already someone else with a similar problem, but I couldn't understand the anwser and I wasn't able to add a coment to receive
more informations. So please help me!
This is my main JavaClass
package ch.androidnewcomer.muckenfangfinal;
import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Date;
import java.util.Random;
public class GameActivity extends Activity implements View.OnClickListener, Runnable{
public static final int DELAY_MILLIS = 1000;
public static final int ZEITSCHEIBEN = 60;
public float massstab;
private int runde;
private int punkte;
private int muecken;
private int gefangeneMuecken;
private int zeit;
private static final long HOECHSTALTER_MS = 2000;
private Random zufallsgenerator = new Random();
private ViewGroup spielbereich;
private Handler handler = new Handler();
private boolean spielLaeuft;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
massstab = getResources().getDisplayMetrics().density;
spielbereich = (ViewGroup)findViewById(R.id.spielbereich);
spielStarten();
}
private void spielStarten() {
spielLaeuft = true;
runde = 0;
punkte = 0;
starteRunde();
}
private void bildschirmAktualisieren() {
TextView tvPunkte = (TextView)findViewById(R.id.points);
tvPunkte.setText(Integer.toString(punkte));
TextView tvRunde = (TextView)findViewById(R.id.round);
tvRunde.setText(Integer.toString(runde));
TextView tvTreffer = (TextView)findViewById(R.id.hits);
tvTreffer.setText(Integer.toString(gefangeneMuecken));
TextView tvZeit = (TextView)findViewById(R.id.time);
tvZeit.setText(Integer.toString(zeit/(1000/DELAY_MILLIS)));
FrameLayout flTreffer = (FrameLayout)findViewById(R.id.bar_hits);
FrameLayout flZeit = (FrameLayout)findViewById(R.id.bar_time);
ViewGroup.LayoutParams lpTreffer = flTreffer.getLayoutParams();
lpTreffer.width = Math.round( massstab * 300 * Math.min( gefangeneMuecken,muecken) / muecken);
ViewGroup.LayoutParams lpZeit = flZeit.getLayoutParams();
lpZeit.width = Math.round( massstab * zeit *300 / ZEITSCHEIBEN);
}
private void zeitHerunterzaehlen() {
zeit = zeit - 1;
if(zeit % (1000/DELAY_MILLIS) == 0) {
float zufallszahl = zufallsgenerator.nextFloat();
double wahrscheinlichkeit = muecken * 1.5;
if (wahrscheinlichkeit > 1) {
eineMueckeAnzeigen();
if (zufallszahl < wahrscheinlichkeit - 1) {
eineMueckeAnzeigen();
}
} else {
if (zufallszahl < wahrscheinlichkeit) {
eineMueckeAnzeigen();
}
}
}
mueckenVerschwinden();
bildschirmAktualisieren();
if(!pruefeSpielende()) {
if(!pruefeRundenende()) {
handler.postDelayed(this, DELAY_MILLIS);
}
}
}
private boolean pruefeRundenende() {
if (gefangeneMuecken >= muecken) {
starteRunde();
return true;
}
return false;
}
private void starteRunde() {
runde = runde +1;
muecken = runde *10;
gefangeneMuecken = 0;
zeit = ZEITSCHEIBEN;
bildschirmAktualisieren();
handler.postDelayed(this, DELAY_MILLIS);
}
private boolean pruefeSpielende() {
if(zeit == 0 && gefangeneMuecken < muecken) {
gameOver();
return true;
}
return false;
}
private void gameOver() {
Dialog dialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
dialog.setContentView(R.layout.gameover);
dialog.show();
spielLaeuft = false;
}
private void mueckenVerschwinden() {
int nummer=0;
while (nummer < spielbereich.getChildCount()) {
ImageView muecke = (ImageView)spielbereich.getChildAt(nummer);
Date geburtsdatum = (Date) muecke.getTag(R.id.geburtsdatum);
long alter = (new Date()).getTime() - geburtsdatum.getTime();
if(alter > HOECHSTALTER_MS) {
spielbereich.removeView(muecke);
}else {
nummer++;
}
}
}
private void eineMueckeAnzeigen() {
int breite = spielbereich.getWidth();
int hoehe = spielbereich.getHeight();
int muecke_breite = (int) Math.round(massstab* 60);
int muecke_hoehe = (int) Math.round(massstab*49);
int links = zufallsgenerator.nextInt(breite - muecke_breite);
int oben = zufallsgenerator.nextInt(hoehe - muecke_hoehe);
ImageView muecke = new ImageView(this);
muecke.setImageResource(R.drawable.muecke);
muecke.setOnClickListener(this);
muecke.setTag(R.id.geburtsdatum, new Date());
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(muecke_breite, muecke_hoehe);
params.leftMargin = links;
params.topMargin = oben;
params.gravity = Gravity.TOP + Gravity.LEFT;
spielbereich.addView(muecke,params);
}
#Override
public void onClick(View muecke) {
gefangeneMuecken++;
punkte += 100;
bildschirmAktualisieren();
spielbereich.removeView(muecke);
}
#Override
public void run() {
zeitHerunterzaehlen();
}
}
The FrameLayout, where I'm trying to display the 'muecke - mosquito' is called 'spielbereich' meaning as much as playground.
And this is the LogCat
12-28 16:19:26.449 5302-5302/ch.androidnewcomer.muckenfangfinal E/AndroidRuntime: FATAL EXCEPTION: main
Process: ch.androidnewcomer.muckenfangfinal, PID: 5302
java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.ImageView
at ch.androidnewcomer.muckenfangfinal.GameActivity.mueckenVerschwinden(GameActivity.java:168)
at ch.androidnewcomer.muckenfangfinal.GameActivity.zeitHerunterzaehlen(GameActivity.java:104)
at ch.androidnewcomer.muckenfangfinal.GameActivity.run(GameActivity.java:218)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
And here is my xmlLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="ch.androidnewcomer.muckenfangfinal.GameActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="61dp">
<TextView
android:id="#+id/round"
android:layout_width="136dp"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="21sp"
android:textStyle="bold" />
<TextView
android:id="#+id/points"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="TextView"
android:textSize="21sp"
android:textStyle="bold" />
</FrameLayout>
<FrameLayout
android:id="#+id/spielbereich"
android:layout_width="match_parent"
android:layout_height="332dp"
android:layout_weight="1">
<LinearLayout
android:id="#+id/hintergrundlinearlayout"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_gravity="bottom"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="35dp">
<FrameLayout
android:id="#+id/bar_hits"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="#android:color/holo_orange_dark">
</FrameLayout>
<TextView
android:id="#+id/hits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/hits"
android:textSize="15sp"
android:textStyle="bold" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/bar_time"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="#android:color/holo_orange_light">
</FrameLayout>
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/time" />
</FrameLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
if you need anymore informations, please tell me.
It would be great if you could tell me exactely how I have to change the code, because I'm really a beginner.
you are casting a linear layout to imageview.You are trying to get a child of frame layout which is a linear layout but you casted it to a image view.thats why this error was happened. casting it to the linearlayout will solve this error.
This is your layout with id spielbereich
<FrameLayout
android:id="#+id/spielbereich"
android:layout_width="match_parent"
android:layout_height="332dp"
android:layout_weight="1">
<LinearLayout
android:id="#+id/hintergrundlinearlayout"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_gravity="bottom"
android:orientation="vertical">
And this is the code where you are trying to cast the childView into an ImageView
private void mueckenVerschwinden() {
int nummer=0;
while (nummer < spielbereich.getChildCount()) {
ImageView muecke = (ImageView)spielbereich.getChildAt(nummer);
Date geburtsdatum = (Date) muecke.getTag(R.id.geburtsdatum);
long alter = (new Date()).getTime() - geburtsdatum.getTime();
if(alter > HOECHSTALTER_MS) {
spielbereich.removeView(muecke);
}else {
nummer++;
}
}
}
ImageView muecke = (ImageView)spielbereich.getChildAt(nummer);
This line is giving you a cast error because nummer = 0 at this point and spielbereich.getChildAt(0) is a LinearLayout

Android:Onclick not finding onclick method

I am attempting to make a custom view that uses buttons, however, the android:Onclick for the two buttons cause the app to crash. The ClickListeners don't work either.
The error I am getting from running the debug tool is :
java.lang.IllegalStateException: Could not find a method addMenu(View) in the activity class com.android.tools.fd.runtime.BootstrapApplication for onClick handler on view class android.widget.Button with id 'increase'
This is My java code :
public class MenuItems extends LinearLayout{
private View plusButton;
private View negateButton;
private EditText priceBox;
private TextView total;
private TextView name;
private int totalItems;
private double totalPrice;
private double price;
public MenuItems(Context context) {
super(context);
init();
}
public MenuItems(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void init()
{
LayoutInflater inflater=LayoutInflater.from(getContext());
inflater.inflate(R.layout.menu_item,this);
plusButton=findViewById(R.id.increase);
negateButton=findViewById(R.id.decrease);
total=(TextView)findViewById(R.id.total);
name=(EditText)findViewById(R.id.ItemName);
priceBox=(EditText)findViewById(R.id.Price) ;
total.setText("5");
negateButton.setBackgroundColor(Color.RED);
plusButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
plusButton.setBackgroundColor(Color.RED);
increase();
}
});
negateButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
decrease();
negateButton.setBackgroundColor(Color.RED);
}
});
price=0;
totalItems=0;
upDateTotal();
String pString=priceBox.getText().toString();
price=Double.parseDouble(pString);
}
public void increase(View view)
{
totalItems++;
upDateTotal();
System.out.println("plus");
plusButton.setBackgroundColor(Color.RED);
}
public void decrease(View v)
{
if(totalItems>0)
totalItems--;
upDateTotal();
System.out.println("minus");
}
This is all of my xml :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/menu_items"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.mohs.joey.seniorproject.MenuItems">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/ItemName"
android:layout_weight="1"
android:textColor="#color/colorAccent"
android:text="name" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:ems="10"
android:id="#+id/Price"
android:textColor="#color/colorAccent"
android:hint="Price"
android:shadowColor="#color/colorAccent"
android:text="0.00" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="-"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="#+id/decrease"
android:layout_weight="1"
android:backgroundTint="#color/colorAccent"
android:onClick="increase"/>
<TextView
android:text="Amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/total"
android:layout_weight="1"
android:textColor="#color/colorAccent" />
<Button
android:text="+"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="#+id/increase"
android:layout_weight="1"
android:backgroundTint="#color/colorAccent"
android:elevation="0dp"
android:onClick="increase" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I access MenuItems in this Method in a separate class :
public void addMenu(View view)
{
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.menu_item, null);
v.setId(menu);
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.backLayer);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
menu++;
}
This is my new main activity:
package com.mohs.joey.seniorproject;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.TextView;
public class ConcessionMenus extends AppCompatActivity {
int menu=0;
private View plusButton;
private View negateButton;
private EditText priceBox;
private TextView total;
private TextView name;
private int totalItems;
private double totalPrice;
private double price;
PopupWindow popup;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_concession_menus);
plusButton=findViewById(R.id.increase);
negateButton=findViewById(R.id.decrease);
total=(TextView)findViewById(R.id.total);
name=(EditText)findViewById(R.id.ItemName);
priceBox=(EditText)findViewById(R.id.Price) ;
// TextView totalPrice=(TextView)findViewById(R.id.totalPrice);
}
public void addMenu(View view)
{
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View vw = vi.inflate(R.layout.menu_item, null);
vw.setId(menu);
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.backLayer);
insertPoint.addView(vw, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
menu++;
}
public Intent newIntent()
{
Intent intent=new Intent(this,Menu.class);
return intent;
}
public void increase(View v)
{
totalItems++;
upDateTotal();
System.out.println("plus");
plusButton.setBackgroundColor(Color.RED);
}
public void decrease(View v)
{
if(totalItems>0)
totalItems--;
upDateTotal();
System.out.println("minus");
}
public void upDateTotal()
{
total.setText(""+totalItems);
totalPrice=price*totalItems;
}
public double totalPrice()
{
return totalPrice;
}
}
Any help would be appreciated.
The problem is when the button want to perform the action when you click on it , it should be able to find the method increase() in your MainActivity class , since the method increase() is on an other class , the button will never find the method and they will crash because you set the your layout xml to your main activity not for the class MenuItem , to fix that just move these to methods to your MainActivity class
OR
Pass a reference of your buttons to the class MenuItems and do what you want there
PS : the ids can be found by typing R.id , but you cannot work with these id since you set the content view to your MainActivity

Categories

Resources