I want to turn off touches on the screen just for 1 or 2 seconds and then turn on. How to do this with a background service as an infinite loop? For instance, if you touch once you cannot touch again in 2 seconds in anywhere on the screen and then keep doing same thing for every touches (not include back, menu or home buttons).
Note: I am using Service for background progress.
You might could do it this way. Disable all views (you can iterate over all children of your root layout) and enable them after two seconds.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout root = (RelativeLayout) findViewById(R.id.activity_main);
final Button btnDisable = (Button) findViewById(R.id.btnDisable);
final Handler handler = new Handler();
btnDisable.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
root.setEnabled(false);
btnDisable.setEnabled(false);
handler.postDelayed(new Runnable() {
#Override
public void run() {
//enable your views after 2 seconds
root.setEnabled(true);
btnDisable.setEnabled(true);
}
}, 2000);
}
});
}
Here is the xml inside of a RelativeLayout with the id activity_main
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:text="disable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnDisable"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
if you want to disable touch only in your app consider bounding service and communicate with your Activity and override MotionEvent related methods, e.g.
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// your code goes here if needed
return true; //disabled touching in whole activity
}
if you want to disable touching in whole system then this is obvoiusly impossible, because is highly unsecure for user...
Related
I'm making an app that has buttons and when a button is clicked, it will play a sound. My problem is that I couldn't find a way to change mSoundButton's background when pressed and released. I'm using 'background' instead of 'src' so I can shrink the button without cutting from edges. I haven't added sounds yet because I want to solve this issue before starting to add sounds.
Here is my codes for the button in MainActivity.java (It works okay, but not in the way I wanted. It changes background when pressed but not released.)
final ImageButton mSoundBtn;
final boolean[] soundBtnClicked = {false};
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(soundBtnClicked[0])
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
else
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
soundBtnClicked[0] = !soundBtnClicked[0];
}
});
and here is my activity_main.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="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="#+id/soundButton"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#drawable/button_not_clicked"
android:contentDescription="TODO" />
</LinearLayout>
UPDATE (PROBLEM SOLVED):
I wanted the mSoundBtn to change image when pressed, then change image again when it is released. I used the Handler class and the postDelayed() method to create a delay between two image changes. It doesn't actually wait for user to release the button but still solved my issue. Following is the solution I found:
public ImageButton mSoundBtn;
Handler h = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
h.postDelayed(new Runnable() {
public void run() {
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
}
}, 1000); // 1 Second
}
});
What happens is when the mSoundBtn is clicked, It changes image and waits for 1000 milliseconds (1 second), then changes back to previous image which creates some kind of animation when it is pressed so the user can understand when the button is pressed.
Thanks for anyone who have tried to help, thanks for reading. :)
You shouldn't define it as 'final'
Sample:
public class SampleActivity extends AppCompatActivity {
//Variables
public ImageButton mSoundBtn;
public boolean isSoundBtnSelected = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
mSoundBtn = findViewById(R.id.soundButton);
mSoundBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(!isSoundBtnSelected)
mSoundBtn.setBackgroundResource(R.drawable.button_clicked);
else
mSoundBtn.setBackgroundResource(R.drawable.button_not_clicked);
isSoundBtnSelected = !isSoundBtnSelected;
}
});
}
}
If I understand you correctly, you want an action to be done after the user removed the finger from the button (meaning the press is done).
Try using OnTouchListener instead of OnClickListener:
imageButton.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_UP)
{
// change background and other stuff...
return true;
}
return false;
}
});
If you only wanted to change the button's background when it pressed, you can use a selector drawable for that, like so:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#color/black" /> <!-- pressed -->
<item android:state_activated="true"
android:drawable="#color/colorAccent" /> <!-- focused -->
<item android:drawable="#color/colorPrimary" /> <!-- default -->
and just place it as the button's background.
Another option is to use a toggle button and OnChecked listener and change the background when the user checks (press) the button. If you want the background to be permanently changed after the first toggle you can implement this by changing the background only after the first toggle.
We have tried two ways to display a Custom Snackbar (1) as a masquerading Dialog which will not move to the bottom of the screen It does however not dismiss the current Activity view just makes it opaque. I know why it is in the center of the screen but I am not able to move it to the bottom. (2) next is a view that takes over the entire screen because it is a new content view that I am guessing dismisses the current Activity view BUT it is at the bottom of the screen.
So my question is how to use design number 1 and move the Dialog to the bottom of screen?
Second question how to stop the new view in design number 2 from dismissing the view of the current Activity? After careful reading and little thought and extreme testing I do not think this is possible! I have posted the code for my two methods below. The XML file uses a Relative Layout as the base container.
public void seeSB(){
setContentView(R.layout.custom_snackbar);
// Line of Code above shows XML file
// Line of code tested but no control over the "viewMyLayout"
//LayoutInflater inflater = LayoutInflater.from(ListActivity.this);
//final View viewMyLayout = inflater.inflate(R.layout.custom_snackbar, null);
//viewMyLayout.setEnabled(true);
Button btnAB = (Button) findViewById(R.id.btnAB);
btnAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// viewMyLayout.setEnabled(false);
// Line above does not function
// CODE BELOW WORKS BUT FAR FROM elegant
setContentView(R.layout.activity_list);
//Intent intent = new Intent(ListActivity.this, ListActivity.class );
//startActivity(intent);
Toast.makeText(getApplicationContext(), "I WAS Clicked", Toast.LENGTH_SHORT).show();
}
});
}
public void displaySB(){
final Dialog openSnack = new Dialog(context);
openSnack.setContentView(R.layout.custom_snackbar);
Button btnAB = (Button)openSnack.findViewById(R.id.btnAB);
TextView tvSB =(TextView)openSnack.findViewById(R.id.tvSB);
//Dialog dialog = new Dialog(ListActivity.this);
//dialog.setContentView(Bottom);
// if YES delete Master Password from TABLE_MPW
btnAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openSnack.dismiss();
Toast.makeText(getApplicationContext(), "I WAS Clicked", Toast.LENGTH_SHORT).show();
}
});
openSnack.show();
}
This is far from functional in my book because the method design has just one Custom Snackbar to look at so you need to work on how to have multiple fixed Custom Snackbars. One suggestion might be to have multiple sub views in your parent view and call the sub view you want. I will post just the sub view I added to the parent XML file and the not so real dynamic method to implement which is implemented in this case with a button click. For this to work in a real application the code would need be called from some method or event.
You might consider a switch statement for multiple views ? ? ?
TAKE NOTE THE RELATIVE LAYOUT has its visibility set to GONE at the start
<RelativeLayout
android:id="#+id/hold_snackbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_Black"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="#+id/tvSB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="#string/snackbar_text"
android:textColor="#color/color_Yellow"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="#+id/btnAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="350dp"
android:layout_marginTop="5dp"
android:background="#color/color_Transparent"
android:focusable="false"
android:text="#string/snackbar_action"
android:textColor="#color/color_Red"
android:textSize="18sp"
android:textStyle="bold" />
</RelativeLayout>
Notice the View subViewGroup is declared when the Activity starts
View subViewGroup;
public void makeSB(View view) {
subViewGroup = findViewById(R.id.hold_snackbar);
subViewGroup.setVisibility(View.VISIBLE);
seeSB();
}
public void seeSB(){
Button btnAB = (Button) findViewById(R.id.btnAB);
btnAB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
subViewGroup.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "I WAS Clicked", Toast.LENGTH_SHORT).show();
}
});
}
Countdown Timer to close a Snackbar with no Action Button
public void makeCDT(View view) {
cdt = new CountDownTimer(5000, 100) {
// 5 sec 5000,100
// 10 sec 10000,100
#Override
public void onTick(long secsUntilFinished) {
etCPW.setText(String.valueOf(secsUntilFinished / 1000));
//etCPW.setText("seconds remaining: " + secsUntilFinished / 1000);
subViewGroup = findViewById(R.id.SB_NO_ACTION);
subViewGroup.setVisibility(View.VISIBLE);
}
#Override
public void onFinish() {
etCPW.setText("Counter Done");
subViewGroup.setVisibility(View.GONE);
if(cdt!=null){
cdt.cancel();
}
}
};
cdt.start();
}
I have a simple LinearLayout that consists of a TextView and an EditText. The behaviour that I'd like to achieve is to be able to click on the EditText and handle it like normal, but treat the encompassing LinearLayout as a button that launches a new activity.
So for example, if the user clicks the space around the button in the view, a new activity is launched. If the user clicks on the EditText, then the keyboard appears and the user can populate the EditText.
Here is the simple onClickListener for the layout, which simply states that it has been clicked:
LinearLayout test = (LinearLayout)findViewById(R.id.linearLayout1);
test.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
System.out.println("layout clicked");
}
});
And the EditText has an OnFocusChangeListener that will simply state when it has gotten focus:
#Override
public void onFocusChange(View v, boolean hasFocus) {
System.out.println("EditText clicked");
}
Results:
-When the user clicks on the layout, the result "layout clicked" is correct
-When the user clicks on the edittext, the result is "layout clicked" followed by "EditText clicked", which is not correct. I'd like to ignore the linear layout's onClick event for this case.
Try creating a FrameLayout that contains a LinearLayout containing the TextView and place the EditText above the LinearLayout. This way you will not need to change anything about the listeners.
So it would be like this:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="200dp" />
</FrameLayout>
Note: use margins to adjust the position of the EditText
I guess something like this should work, although it isn't the cleanest solution.
Declare a runnable that should be executed when the layout is clicked.
final Handler handler = new Handler();
Runnable layoutPressed = new Runnable() {
public void run() {
// LAYOUT CLICKED
}
};
Then start this runnable in your layout onClickListener.
LinearLayout test = (LinearLayout)findViewById(R.id.linearLayout1);
test.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
handler.postDelayed(layoutPressed, 100);
}
});
Cancel the runnable in onFocusChange.
#Override
public void onFocusChange(View v, boolean hasFocus) {
handler.removeCallbacks(layoutPressed);
// EditText clicked
}
So whenever you click the editText, the onClick of your layout will get called first, but the actions will get cancelled when onFocusChange of the editText is called.
When you click the layout, onClick will get called and will execute its actions with a 100 msec delay.
You might have to modify the delay of the runnable.
I have a need to show a minimally-intrusive non-blocking notification which is not tied to the activity it was shown in (like a Toast) and which is clickable. Anyone have any idea whether or not this is possible? Unfortunately, it appears that Toast notifications (custom or otherwise) are not clickable (i.e. setting an OnClickListener on its views has no effect). All the alternatives that I'm aware of (i.e. AlertDialog, PopupWindow and Crouton) seem to show a notification which is tied to the activity it was shown in (i.e. they won't continue showing when the activity finishes). Any suggestions?
You can use PopupWindow, add an onClickListener and add a handler to auto cancel it after n times (just like the behavior of a toast). Something like this:
public static void showToast(Activity a, String title, String message) {
// inflate your xml layout
LayoutInflater inflater = a.getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) a.findViewById(R.id.toast_layout_root));
// set the custom display
((TextView) layout.findViewById(R.id.title)).setText(title);
((TextView) layout.findViewById(R.id.message)).setText(message);
// initialize your popupWindow and use your custom layout as the view
final PopupWindow pw = new PopupWindow(layout,
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT, true);
// set windowType to TYPE_TOAST (requires API 23 above)
// this will make popupWindow still appear even the activity was closed
pw.setWindowLayoutType(WindowManager.LayoutParams.TYPE_TOAST);
pw.showAtLocation(layout, Gravity.CENTER | Gravity.TOP, 0, 500);
// handle popupWindow click event
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do anything when popupWindow was clicked
pw.dismiss(); // dismiss the window
}
});
// dismiss the popup window after 3sec
new Handler().postDelayed(new Runnable() {
public void run() {
pw.dismiss();
}
}, 3000);
}
xml layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toast_layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:orientation="vertical"
android:elevation="10dp"
android:padding="20dp">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFF"
android:textStyle="bold"/>
<TextView
android:id="#+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#FFF"/>
</LinearLayout>
You are right, a Toast object has no way to be interacted with, but there are many libraries out there that will give you the same look and feel as a toast, but with some interactivity. The one I use is https://github.com/JohnPersano/SuperToasts
I think what you need is in fact a PopupWindowwhich can be seen here "http://developer.android.com/reference/android/widget/PopupWindow.html".
Toasts have a very specific task, which is to inform the user, without any input from them. So instead of trying to extend the purpose of the Toast, use the PopupWindow which can be interacted with by the user.
A 'Dialog' type of activity will probably be your best bet.
In manifest:
<activity android:name=".ToastLikeActivity"
android:theme="#android:style/Theme.Dialog"
android:label="#string/label"
></activity>
And timeout the activity within the onCreate():
class ToastLikeActivity extends Activity {
#Override
public void onCreate(Bundle state)
// auto-kill activity after X seconds <-------------------------
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
ToastLikeActivity.this.finish(); // kill after X seconds
}
}
}, VisibleTimeSecs*1000);
}
To display the dialog start it as with any other activity:
Intent i = new Intent(this, ToastLikeActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
And it will show up and automatically go away after X seconds.
Such a popup will not be tied to the caller activity. In fact - it will not even require a caller activity. You
can activate it (bad idea, but possible) even from a service.
You can implement basically any kind of sensitive (i.e. accepting user's clicks) interface you want to
the ToastLikeActivity. Especially: you can make its exteriors transparent, giving it a dialog-likke looks.
I would like to create a loop somewhere in my Android code that changes the color of a drawable rectangle between two colors continuously at some rate. I would like to start and stop its blinking using two buttons. I have done a lot of research, but just can't seem to figure out how to do it. I am new to android and do not have experience with run() methods. But I am guessing I have to make some kind of rectangle class with a run() method that will animate it into changing colors.
I am also fairly new to android, but I will give it a shot.
Since you say you want it to blink, you should be able to switch the actual image between, lets say, blue and red, with a simple 'for' loop. When the button is pressed, you could change the status of a boolean from false to true. Then, when the 'for' statement is not true anymore, it jumps to the next set of code, which stops it. Here is what I would do.
Your XML for the two buttons:
<Button
android:id="#+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start"
android:Clickable="true"
android:onClick="start"
/>
<Button
android:id="#+id/stop" <!-- Gives the button an ID to use in java code -->
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Stop" <!-- sets the text on the button -->
android:Clickable="true" <!-- makes the button clickable -->
android:onClick="stop" <!-- The method it calls when it is clicked, removes the necessity of an OnClickListener -->
/>
Now, you would have 2 ImageViews: blue_rectangle and red_rectangle, both in the same place in the layout. Here is the XML for the two ImageViews
<ImageView
android:id="#+id/blue_rectangle"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="5dp"
android:src="#drawable/blue_rectangle" />
<ImageView
android:id="#+id/red_rectangle"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginLeft="50dp"
android:layout_marginTop="5dp"
android:src="#drawable/red_rectangle" />
This next part is the tricky part.
Here is the Java.
package your.package.name.thingy.here;
//everything it tells you to import goes here
public class BlinkingActivity extends Activity{
ImageView blueRectangle;
ImageView redRectangle;
Button start;
Button stop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.yourLayout);
blueRectangle = (ImageView) findViewById(R.id.blue_rectangle);
redRectangle = (ImageView) findViewById(R.id.red_rectangle);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
Boolean isBlinking = new Boolean(false);
blinkRectangle(whateverVariableThisNeeds);
}
public static void blinkRectangle(View view){
blueRectangle.setVisibility(View.INVISIBLE);
redRectangle.setVisibility(View.INVISIBLE);
for(initialization; isBlinking; update){
blueRectangle.setVisibility(View.VISIBLE);
blueRectangle.postDelayed(new Runnable() {
#Override
public void run() {
blueRectangle.setVisibility(View.INVISIBLE);
}
}, 2000); //the 2000 is the number of milliseconds for how long blue is visible
redRectangle.setVisibility(View.VISIBLE);
redRectangle.postDelayed(new Runnable() {
#Override
public void run(){
redRectangle.setVisibility(View.INVISIBLE);
}
}, 2000);
blueRectangle.setVisibility(View.VISIBLE); //This prevents a bug where if the user hits the stop button at just the right time, both rectangles will be invisible.
}
public static void start(View view){ //no need to call this anywhere, the XML onClick does it for you
isBlinking = true; //I think this is how you set a boolean, if not, correct me.
}
public static void stop(View view){//same here
isBlinking = false; //again, correct me if I'm wrong.
}
}
Here is what the code basically does.
It has a boolean which is defaulted to false. While it is false, the rectangle does not blink. While it is true, the for statement in blinkRectangle() runs. That for loop makes the blue on visible, waits 2 seconds, makes it invisible, makes the red one visible, waits two seconds, and repeats. The start() and stop() methods switch the boolean to true and false, respectively. I think this type of for loop re-checks the boolean when it gets back to the top. I have never worked with it before. That's what I could gather from the website I looked at.
Well, I think that about does it. If you don't understand what any of the code does, or it doesn't work, or I have the question wrong, or I am just downright wrong, or ANYTHING, just comment on this answer. I hope this works!
Good Luck!
P.S. Here are the websites I used for reference
http://www.tutorialspoint.com/java/java_loop_control.htm
http://www.java-examples.com/java-boolean-example
Wow...I just realized this question is 2 years old. Still, I hope this helps you!