Consider a relative layout with three buttons of variable sizes with no anchoring arguments resulting in all being drawn at the top-left corner of the screen. Consider a single physical touch event being generated. Which of these buttons will see this event? If that all three have registered as onTouch listeners. How is the process behind this behavior ?
RelativeLayout creates a hierarchy between elements inside of it. The item you put to the lowest line will be on top of all others. And when you click, its onClick method will be called. For example you have two buttons inside of RelativeLayout like:
<Button
android:id="#+id/button_a"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="You won't see this" />
<Button
android:id="#+id/button_b"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="You will see this" />
And let's say your Java code is:
findViewById(R.id.button_a).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(this, "Button A clicked.", Toast.LENGTH_LONG).show();
}
});
findViewById(R.id.button_b).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getContext(), "Button B clicked", Toast.LENGTH_LONG).show();
}
});
In this case, you will always see the Button B clicked Toast on the screen, when you tap on these buttons.
Related
The premise is quite simple. I have a list of items, and each item has a TextView containing the title of the item, and a Switch showing whether the item is on or off. Instead of tapping on the Switch to toggle the item being on or off, I want to be able to click anywhere on the item to toggle it. Basically:
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="toggleSwitch">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Switch
android:id="#+id/switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
However, this will create a nested layout when used in a screen, which might be bad for performance. I was wondering, since this ConstraintLayout is literally just a container with an onClick, whether there was a way to implement this layout in a way which avoids nested layouts. Thanks!
You can just give your textView and your button the same method that will be called on click, that way on every view click (anywhere on the item) you will call your method.
For example:
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//change you switch state
}
});
switch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//change you switch state
}
});
I have a blank activity in Android Studio, and I have performed the following instructions but it is not working when I run the program.
Select the button and look for properties/attributes panel on the right.
Assign the name onClick to the android:onClick property of your Button.
Implement the following method in the Main_Activity file:
public void onClick (View view) {
Toast.makeText(this, "Button 1 pressed", Toast.LENGTH_LONG).show();
}
When I try to run this I get errors like:
expecting a member declaration
function declaration must have a name
Button yourButton = (Button)findViewById(R.id.your_button_id)
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(this, "Button 1 pressed", Toast.LENGTH_LONG).show();
}
});
Please try this in Java.
1)in Xml file of you Activity set onClick property of button with specified function name
android:onClick:"onClick"
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:onClick="onButtonClick"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
2)after this put same function inside your activity but with parameter like this
public void onClick (View view)
public void onButtonClick(View view){
Toast.makeText(this, "Button 1 pressed", Toast.LENGTH_LONG).show();
}
3) when you click on button provided method gets called
Note: function name can be anything but access specifier, return type and parameter has to be same.
Using the XML attribute android:onClick to trigger a click event. Only need two steps:
1.assign android:onClick to button like this:
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="btnClicked" />
2 In activity define a function named btnClicked like this:
public void btnClicked(View v) {
Log.d("MR.bool", "Button1 was clicked ");
}
Notice: don't mix this way with setOnClickListener,just only above two steps.
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'm creating a compose screen for my app. I have a ScrollView which contains a RelativeView which in turn contains two things: the EditText where the user types a message, and an ImageView whose visibility is toggled on and off depending on whether an image is attached to the status or not. Here's that part of my layout XML.
<!-- #dimen/bigGap = 8dp -->
<ScrollView android:id="#+id/parentScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_marginTop="#dimen/bigGap"
android:layout_marginRight="#dimen/bigGap"
android:layout_marginLeft="#dimen/bigGap"
android:layout_marginBottom="#dimen/bigGap"
android:layout_above="#+id/footer"
android:background="#006400"
> <!-- green background color -->
<RelativeLayout android:id="#+id/parentLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFD700"> <!-- yellow background color -->
<EditText android:id="#+id/postText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#dddddd"
android:inputType="textMultiLine"
android:gravity="top|left"
/> <!-- gray background color -->
<ImageView android:id="#+id/postImage"
android:layout_width="#dimen/thumbnailSize"
android:layout_height="#dimen/thumbnailSize"
android:visibility="gone"
android:layout_below="#id/postText"
/>
</RelativeLayout>
</ScrollView>
Because my EditText's height is wrap_content, the whole thing starts off with a single line of gray background (the EditText) on top of a yellow background (the RelativeLayout, which fully covers the green background of the ScrollView). However, I'll later change all the views' backgrounds to white (to make them look like a single component) and it will be counter-intuitive for the user to be able to tap only that single line of EditText to make the keyboard pop up.
What I want to do is to redirect the click and long click actions of the RelativeLayout to the click and long click actions of the EditText, but my code below doesn't work. Help?
final EditText editText = (EditText) findViewById(R.id.postText);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.parentLinearLayout);
rl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Logger.d("onClick invoked!");
editText.performClick();
}
});
rl.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Logger.d("onLongClick invoked!");
return editText.performLongClick();
}
});
My intention here is so that when the RelativeLayout is clicked, the keyboard pops up (as it does when done to an EditText) and when long-pressed, display the cut/copy/paste/text selection options (same behavior with EditText).
From the description, What you actually want is to open the keyboard. So your title for the question suggests a solution, not the actual problem.
call this from your click listener (or immediately when you show the page):
((InputMethodManager) myActivity
.getSystemService(Context.INPUT_METHOD_SERVICE))
.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);
Edit:
You must also call editText.requestFocus(); (#Phil is right), but from my experience it's not enough to open the keyboard, so you'll need also the ugly code above.
What you want is for your EditText to gain focus (which in-turn causes the keyboard to show):
rl.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Logger.d("onClick invoked!");
editText.requestFocus();
}
});
rl.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Logger.d("onLongClick invoked!");
editText.requestFocus();
return true;
}
});
I have a button which is called Check, I want it to be invisible and visible as I click each time on it, as If its visible and I clicked it will become invisible and verse vies !
But my code doesn't work ! any ideas ?
Button Check ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.settings);
Check = (Button)findViewById(R.id.checkButton);
Check.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View View) {
if (View.getVisibility() == android.view.View.VISIBLE)
View.setVisibility(android.view.View.INVISIBLE);
else if (View.getVisibility() == android.view.View.INVISIBLE)
View.setVisibility(android.view.View.VISIBLE);
}
});
In my activity its visible at the beginning and when I click on it, it become invisible, BUT when I click again it stays invisible !
Change your code to this,
Check.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (v.isShown())
v.setVisibility(View.INVISIBLE);
else
v.setVisibility(View.VISIBLE);
}
But i think problem is, when button goes invisible, you are not getting any click event on it. First make sure that onClick method get call when button is invisible.
An invisible button will not dispatch any interaction event. So instead of setting button's visibility to the invisible, you can set a transparent or blank background or something like that.
But i personally believe, you should change your use-case because why one will click on the invisible button.
Try This:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="abcd" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:onClick="abc"
android:text="Button" />
</LinearLayout>
public void abc(View v) {
v.setVisibility(View.INVISIBLE);
}
public void abcd(View v) {
v.findViewById(R.id.button1).setVisibility(View.VISIBLE);
}
Invisible Items don't receive on-click event. So the only way you can receive a click on invisible is by receiving on some other view in place of the invisible view. The above solution wraps the button in a layout, so when button is invisible the on-click is passed on to layout, which handles the event and do accordingly. If you have a high usage of such layout you can also create a custom button with above mechanism.