Android Button receives OnTouch event but not OnClick - android

I have the following layout in which I'm trying to register an OnClickListener for the button list_item_setup_step_button_start. the Button receives touch events but no click events. any help is appreciated.
<RelativeLayout
android:id="#+id/list_item_setup_step_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/list_item_setup_step_label"
android:layout_width="#dimen/list_item_setup_state_label_width"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="#color/activity_setup_step_state_next_color"
android:clickable="false"/>
<FrameLayout
android:id="#+id/list_item_setup_step_frame_layout_progress"
android:layout_width="#dimen/list_item_setup_step_progress_bar_size"
android:layout_height="match_parent">
<com.mikhaellopez.circularprogressbar.CircularProgressBar
android:id="#+id/list_item_setup_step_progress_bar"
android:layout_width="40dp"
android:layout_height="40dp"
app:cpb_background_progressbar_color="#FFCDD2"
app:cpb_progressbar_color="#F44336"
android:visibility="invisible"
android:layout_gravity="center_vertical|center_horizontal"/>
<Button
android:id="#+id/list_item_setup_step_button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:padding="#dimen/text_margin_normal"
android:background="#color/color_accent_default"
android:textColor="#color/text_color_light"
android:visibility="invisible"
android:clickable="true"
android:textSize="#dimen/text_size_normal"
android:layout_marginLeft="#dimen/text_margin_normal"/>
</FrameLayout>
<LinearLayout
android:layout_toLeftOf="#id/list_item_setup_step_label"
android:layout_toRightOf="#id/list_item_setup_step_frame_layout_progress"
android:layout_marginRight="#dimen/text_margin_normal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/list_item_setup_step_text_view_title"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textSize="16sp"
android:gravity="right|center_vertical"
android:textColor="#color/text_color_light"/>
<TextView
android:id="#+id/list_item_setup_step_text_view_status"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="right|center_vertical"
android:textColor="#color/text_color_light" />
</LinearLayout>
</RelativeLayout>
this is the code for the listener (I have a custom ScrollView which ignores touch events so that it can only be scrolled programmatically), the 'Clicked' log never appears and the functions aren't called.
private void handleStartButton() {
currentStepStartButton = (Button) stepViews[currentPhase][currentStep].findViewById(R.id.list_item_setup_step_button_start);
currentStepStartButton.setTypeface(BaseActivity.getFont(this));
final TextView status = (TextView) stepViews[currentPhase][currentStep].findViewById(R.id.list_item_setup_step_text_view_status);
progressBar = (CircularProgressBar) stepViews[currentPhase][currentStep].findViewById(R.id.list_item_setup_step_progress_bar) ;
progressBar.setProgress(0);
StyleHelper.applyStyle(this, progressBar);
status.setTypeface(BaseActivity.getFont(this));
if(currentStep == 0 && currentPhase == 0) {
status.setText(getString(R.string.activity_setup_press_button_to_begin));
currentStepStartButton.setText(getString(R.string.commons_start));
} else {
status.setText(getString(R.string.activity_setup_press_button_to_continue));
currentStepStartButton.setText(getString(R.string.commons_start));
}
currentStepStartButton.setVisibility(View.VISIBLE);
currentStepStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e(Constants.DEBUG_TAG, "Clicked") ;
currentStepStartButton.setVisibility(View.INVISIBLE);
handleCurrentStepAction();
}
});
}
EDIT:
The following method was being called before the method which set the listener:
private void requestPermissions() {
int currentAPIVersion = android.os.Build.VERSION.SDK_INT ;
if (currentAPIVersion >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{
android.Manifest.permission.SEND_SMS,
android.Manifest.permission.RECEIVE_SMS
}, 1);
}
}
Once this method was removed, the OnClickListener started working again. I don't really have any idea why. Any theories ?

There seem to be some interference from your other code (which is not visible in this question) since the button click method works if the code you provided, except for those parts which are not visible, is inserted into a new project.
Java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_2);
final Button currentStepStartButton = (Button) findViewById(R.id.list_item_setup_step_button_start);
currentStepStartButton.setVisibility(View.VISIBLE);
currentStepStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("MainActivity", "Clicked");
currentStepStartButton.setVisibility(View.INVISIBLE);
}
});
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/list_item_setup_step_layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/list_item_setup_step_frame_layout_progress"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/list_item_setup_step_button_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="invisible"
android:clickable="true"/>
</FrameLayout>
</RelativeLayout>
</LinearLayout>
Try to temporarily disable unnecessary features for the button to work to zero in on the issue.

Well I faced the same problem while working on another project and figured what was really wrong here.
The problem, as suggested in the question itself, rises from the use of requestPermissions method. Although calling this method in case the permission its trying to acquire is already granted might seem to not show a dialog over the current activity, some invisible overlay seems to be added anyway which also appears to be clickable.
The solution hence is to always check if one already has the permissions one is trying to acquire and only fire up requestPermissions in case those permissions are not granted yet.

Related

Android SeekBarChangeListener and TouchListener No Events

I'm having an issue with button click events and seekbar events not firing. When I drag on my seekbar, the slider changes position visually but there's no event being fired in my OnSeekBarChangedListener. I also have an ImageButton that should receive click events but it does not fire either. The MyView at the bottom here handles touch events properly. It holds a GLSurfaceView that I can pan around and pinch-zoom on. What could be causing the events to not fire?
Here's my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/tec_root">
<ImageButton
android:id="#+id/button_star"
android:contentDescription="#string/star_description"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:src="#drawable/star_empty"
android:background="#00000000"
android:scaleType="fitXY"/>
<LinearLayout
android:id="#+id/view_plot"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/button_star"/>
<SeekBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/button_star"
android:layout_toStartOf="#id/button_star"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:progress="50"
android:layout_alignBaseline="#id/button_star"
android:id="#+id/seekbar" />
</RelativeLayout>
And here are the listeners:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
starred = prefs.getBoolean("starred", false);
final ImageButton starButton = (ImageButton) findViewById(R.id.button_star);
starButton.setImageDrawable(ContextCompat.getDrawable(this, (starred ? R.drawable.star_filled :
R.drawable.star_empty)));
starButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
starred = !starred;
prefsEditor = prefs.edit();
prefsEditor.putBoolean("starred", starred);
prefsEditor.apply();
starButton.setImageDrawable(ContextCompat.getDrawable(getApplicationContext(),
(starred ? R.drawable.star_filled : R.drawable.star_empty)));
}
});
((SeekBar) findViewById(R.id.seekbar)).setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
Log.e("TEST", "Seekbar onProgressChanged called");
Toast.makeText(getApplicationContext(), "Seekbar fired", Toast.LENGTH_SHORT).show();
// respond to update
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
MyView myView = new MyView(this, points, false);
((LinearLayout) findViewById(R.id.view_plot)).addView(myView);
}
try this, replace LinearLayout with FrameLayout, it's not best at perfomance but works well
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tec_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<SeekBar
android:id="#+id/seekbar"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:background="#ABABAB"
android:layout_weight="1"
android:progress="50" />
<ImageButton
android:id="#+id/button_star"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="#00000000"
android:contentDescription="#string/star_description"
android:scaleType="fitXY"
android:src="#drawable/star_empty" />
</LinearLayout>
<FrameLayout
android:id="#+id/view_plot"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
</LinearLayout>
Try changing your code to this:
MyView myView = new MyView(this, points, false);
myView.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
((LinearLayout) findViewById(R.id.view_plot)).addView(myView);
Could this be reproduced by removing the GLSurfaceView?
If so, changing SurfaceView.setZOrderOnTop might help.
http://developer.android.com/reference/android/view/SurfaceView.html#setZOrderOnTop(boolean)
there may be issue of layout design so please rearrange the components of ui.
seekbar is over imagebutton so android platform is not able to detect touch event.
set layout_below in seekbar
One possible reason for this could be touch handling in custom MyView. We have to be very careful about return value of onTouchEvent() function. Try returning "true" from your onTouchEvent() if you are consuming event else return "false".

Display a loading overlay on Android screen

I'm looking to display an overlay over the screen that shows a little loading ticker or possibly even some text whilst my app attempts to log into the server. My login screen is all inside of a vertical linear layout.
The effect I'm trying to achieve is something like this: http://docs.xamarin.com/recipes/ios/standard_controls/popovers/display_a_loading_message
Maybe too late, but I guess somebody might find it useful.
Activity:
public class MainActivity extends Activity implements View.OnClickListener {
String myLog = "myLog";
AlphaAnimation inAnimation;
AlphaAnimation outAnimation;
FrameLayout progressBarHolder;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
progressBarHolder = (FrameLayout) findViewById(R.id.progressBarHolder);
button.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
new MyTask().execute();
break;
}
}
private class MyTask extends AsyncTask <Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
button.setEnabled(false);
inAnimation = new AlphaAnimation(0f, 1f);
inAnimation.setDuration(200);
progressBarHolder.setAnimation(inAnimation);
progressBarHolder.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
outAnimation = new AlphaAnimation(1f, 0f);
outAnimation.setDuration(200);
progressBarHolder.setAnimation(outAnimation);
progressBarHolder.setVisibility(View.GONE);
button.setEnabled(true);
}
#Override
protected Void doInBackground(Void... params) {
try {
for (int i = 0; i < 5; i++) {
Log.d(myLog, "Emulating some task.. Step " + i);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
}
Layout xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start doing stuff"
android:id="#+id/button"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Do Some Stuff"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<FrameLayout
android:id="#+id/progressBarHolder"
android:animateLayoutChanges="true"
android:visibility="gone"
android:alpha="0.4"
android:background="#000000"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center" />
</FrameLayout>
</RelativeLayout>
I like the approach in Kostya But's answer.
Building on that, here's a couple of ideas to make the same overlay easily reusable across your app:
Consider putting the overlay FrameLayout in a separate layout file, e.g. res/layout/include_progress_overlay:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/progress_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.4"
android:animateLayoutChanges="true"
android:background="#android:color/black"
android:clickable="true"
android:visibility="gone">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
(One thing I added in the overlay FrameLayout is android:clickable="true". So while the overlay is shown, it prevents clicks going through to UI elements underneath it. At least in my typical use cases this is what I want.)
Then include it where needed:
<!-- Progress bar overlay; shown while login is in progress -->
<include layout="#layout/include_progress_overlay"/>
And in code:
View progressOverlay;
[...]
progressOverlay = findViewById(R.id.progress_overlay);
[...]
// Show progress overlay (with animation):
AndroidUtils.animateView(progressOverlay, View.VISIBLE, 0.4f, 200);
[...]
// Hide it (with animation):
AndroidUtils.animateView(progressOverlay, View.GONE, 0, 200);
With animation code extracted into a util method:
/**
* #param view View to animate
* #param toVisibility Visibility at the end of animation
* #param toAlpha Alpha at the end of animation
* #param duration Animation duration in ms
*/
public static void animateView(final View view, final int toVisibility, float toAlpha, int duration) {
boolean show = toVisibility == View.VISIBLE;
if (show) {
view.setAlpha(0);
}
view.setVisibility(View.VISIBLE);
view.animate()
.setDuration(duration)
.alpha(show ? toAlpha : 0)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
view.setVisibility(toVisibility);
}
});
}
(Here using view.animate(), added in API 12, instead of AlphaAnimation.)
I have ProgressBar in Relative Layout and I hide or show it respectively. And yes activity can be transparent.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/hsvBackgroundContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
</LinearLayout>
<ProgressBar
android:id="#+id/pbProgess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>
A spinner with a message over the application can be created using a ProgressDialog. Whilst it doesn't achieve the exact effect as in the picture, it's a good way to show that the app is working.
I made a library (Not well documented yet, Do it within a few days after reducing some work pressure) to do this kind of progress dialog. I made it the very reusable way that's why you need to just configure it one time and hide show it anywhere in your app just calling a single line of code. The configuration -
LoadingPopup.getInstance(this)
.customLoading()
.setCustomViewID(R.layout.yourProgressLayout,R.color.yourProgressBackgroundColor)
.doIntentionalDelay()
.setDelayDurationInMillSec(5000)
.setBackgroundOpacity(70)/*How much transparent you want your background*/
.build();
For showing the progress -
LoadingPopup.showLoadingPopUp();
For hiding the progress-
LoadingPopup.hideLoadingPopUp();
I had the same question, I tried the solutions but was not the best UI so, I did the followings steps.
Divide the screen in 2 views: Content and ProgressBar.
When you want to call the ProgressBar you change the visibility to VISIBLE and add the following properties to the content id=content and not to the progressBar container.
content.background="#000000"
content.alpha="0.4"
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
tools:context=".MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView"
android:layout_centerHorizontal="true"
android:text="Start doing stuff" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Do Some Stuff"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"
android:visibility="gone" />
</FrameLayout>
You have to make a background operation using thread concept like AsyncTask. Using this you can hide the actual work from the UI part. And AsyncTask will get unallocated after your operations are completed.
Create a subclass of AsyncTask
Use AsyncTask to do background work
Call onPreExecute() to initialize task
Use a progressbar with setIndeterminate(true) to enable the
indeterminate mode
Call onProgressUpdate() to animate your progressbar to let the user
know some work is being done
Use incrementProgressBy() for increment progressbar content by a
specific value
Call doInBackground()and do the background work here
Catch an InterruptedException object to find end of background
operation
Call onPostExecute() to denote the end of operation and show the
result
Android's indeterminate ProgressDialog tutorial
Splash screen while loading resources in android app

Add a RelativeLayout dynamically to a LinearLayout in Android

I have been trying for a while to work out how to dynamically create a RelativeLayout with multiple views inside (e.g. TextView, ProgressBar) a LinearLayout to create a RelativeLayout beneath the previous one after every button click. Please can anyone look at my code and see if there is anything that I can do to solve this issue.
Here is the code:
activity_test_container.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frag1ScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/testLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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=".TestContainerActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/testContainerTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/testContainerTextView1"
android:layout_marginBottom="16dp"
android:text="TextView2" />
<TextView
android:id="#+id/testContainerTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="TextView1" />
<Button
android:id="#+id/testContainerButton1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/testContainerTextView2"
android:text="Button" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
container.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginBottom="16dp"
android:background="#color/display_panels" >
<ProgressBar
android:id="#+id/containerProgressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/containerImageButton2"
android:max="100"
android:progress="40" />
<TextView
android:id="#+id/containerTextView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerTextView6"
android:layout_alignLeft="#+id/containerProgressBar1"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/containerTextView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerProgressBar1"
android:layout_centerHorizontal="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageButton
android:id="#+id/containerImageButton2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/containerTextView6"
android:background="#color/display_panels"
android:contentDescription="Okay icon"
android:src="#drawable/ic_green_ok" />
</RelativeLayout>
TestContainerActivity.java
public class TestContainerActivity extends Activity implements OnClickListener {
LinearLayout containerLayout;
Button testButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test_container, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v==testButton){
createNewLayout();
}
}
public void createNewLayout(){
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View addView = layoutInflater.inflate(R.layout.container, null);
containerLayout.addView(addView);
}
}
I'm not entirely sure what you're problem is, but I suspect it's that the rows are not showing up at all because I don't see where you attach the listener to the Button. To handle a click event, an OnClickListener needs to be set on your View. Though this is commonly done with Buttons, OnClickListeners can be set on any view, so any size/shape widget can be made clickable. This is done with the setOnClickListener method of a View. There are multiple ways to do this, try modifying your onCreate like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(this);
}
An alternative method to setting your listener would be to create the listener in onCreate rather than using the Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createNewLayout();
}
});
}
In this case, you wouldn't need to have your Activity implement OnClickListener. I usually only will do something like that if I have many buttons with similar functionality, where creating listeners for each will cause a performance hit. For more isolated cases like this, I prefer to set individual Listeners since the performance difference will be negligible, but that's just my personal preference.
Hope this helps! If your problem was actually based somewhere else, please modify your question and I'll try my best to assist! Also, keep in mind that you can use the Log class to post information about execution in your LogCat output. It really helps with debugging! I suspect that if you put some logging in your listener and createNewLayout() right now, you'd see that the logging never happens because those methods are never called.

Android - ImageButton onClick working in ICS and JB but not in GB

I've created a somewhat simple layout with a total of 4 buttons: 3 buttons at the bottom of the layout are side by side (in a RelativeLayout) and on huge button almost in the middle of the screen.
On Ice Cream Sandwich and Jellybean, I can click any of the buttons and everything works fine (i.e.The respective onClick functions are called) but weirdly enough on Gingerbread any of the 3 buttons at the bottom work but not the one in the middle. onClick fires off many instructions, none of which are being executed so as far as I can tell, it's not being called and I don't know why.
Code for layout is given below. Any help is greatly appreciated!
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/main_off"
android:orientation="vertical"
android:weightSum="10" >
<ImageButton
android:id="#+id/button_activate"
android:layout_width="155dp"
android:layout_height="0dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="170dp"
android:layout_weight="7.2"
android:background="#drawable/transparent"
android:clickable="true"
android:contentDescription="#string/app_name"
android:onClick="activate"
android:src="#drawable/transparent" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="30dp"
android:layout_marginTop="80dp"
android:layout_weight="2" >
<ImageButton
android:id="#+id/button_help"
android:layout_width="90dp"
android:layout_height="fill_parent"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="#drawable/transparent"
android:clickable="true"
android:contentDescription="#string/app_name"
android:onClick="openhelp"
android:src="#drawable/transparent" />
<ImageButton
android:id="#+id/button_settings"
android:layout_width="55dp"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_marginTop="0dp"
android:layout_toLeftOf="#+id/button_help"
android:background="#drawable/transparent"
android:clickable="true"
android:contentDescription="#string/app_name"
android:onClick="opensettings"
android:src="#drawable/transparent" />
<ImageButton
android:id="#+id/button_contact"
android:layout_width="70dp"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_marginTop="0dp"
android:layout_toRightOf="#+id/button_help"
android:background="#drawable/transparent"
android:clickable="true"
android:contentDescription="#string/app_name"
android:onClick="opencontact"
android:src="#drawable/transparent" />
</RelativeLayout>
</LinearLayout>
Activity that calls the layout (main.xml):
//bunch of imports
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout) findViewById (R.id.main_layout);
boolean serviceOn = isMyServiceRunning();
if(serviceOn==true) layout.setBackgroundResource(R.drawable.main_on);
else if (serviceOn==false) layout.setBackgroundResource(R.drawable.main_off);
}
#Override
protected void onResume() {
super.onResume();
LinearLayout layout = (LinearLayout) findViewById (R.id.main_layout);
boolean serviceIsOn = isMyServiceRunning();
if(serviceIsOn==true) layout.setBackgroundResource(R.drawable.main_on);
else if (serviceIsOn==false) layout.setBackgroundResource(R.drawable.main_off);
}
public void activate(View v){
LinearLayout layout = (LinearLayout) findViewById (R.id.main_layout);
Resources res = getResources();
Drawable on = res.getDrawable(R.drawable.main_on);
Drawable off = res.getDrawable(R.drawable.main_off);
if (layout.getBackground().getConstantState() == off.getConstantState()){
layout.setBackgroundResource(R.drawable.main_on);
Toast.makeText(getApplicationContext(), "App has been activated", Toast.LENGTH_SHORT).show();
turnon();
}
else if (layout.getBackground().getConstantState() == on.getConstantState()){
layout.setBackgroundResource(R.drawable.main_off);
Toast.makeText(getApplicationContext(), "App has been deactivated", Toast.LENGTH_SHORT).show();
turnoff();
}
}
}
I can run this fine on my emulator for both 2.2 and 2.3.
The only thing I can suggest is to try to remove drawables (maybe some settings there are screwing things up), or try to make your relative layout height 0dp, since you are using weight_sum

Button onClick not detected with a ListView and ListActivity

I have the following layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:text="Height"
android:layout_height="wrap_content"
android:id="#+id/buttonHeight"
android:layout_width="wrap_content"
android:layout_weight="15"
android:onClick="OnClickHeight">
</Button>
<Button
android:text="Width"
android:layout_height="wrap_content"
android:id="#+id/buttonWidth"
android:layout_width="wrap_content"
android:layout_toRightOf="#id/buttonHeight"
android:layout_weight="1"
android:onClick="onClickWidth">
</Button>
</LinearLayout>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:dividerHeight="1px"
android:drawSelectorOnTop="false"/>
</RelativeLayout>
I then have a class that extends ListActivity in which I have my onClickWidth and onClickHeight methods, for example:
public void onClickWidth(View v)
{
// does stuff
}
However, these onClick events are not being handled. If I change the class to extend Activity, instead of ListActivity, and also remove the ListView from my layout, then it is detected!
I have tried to set android:clickable="true", played around with the android:focusable attribute, and various other things, but I just cannot get this to work. How can I resolve this, or is this simply not allowed?
Can you tell us what are you try to do? And why do you need ListActivity?
Sorry for edditing:P
You could take a look here: How to handle ListView click in Android
put OnClicklistener within adapter itself .
Rather then using the onClick stuff in the layout, have you tried something like this:
Button buttonWidth = (Button)findViewById(R.id.buttonWidth);
buttonWidth.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//do stuff
}
});
Then do the same for buttonHeight.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_land);
Button btn = (Button) findViewbyid(R.id.buttonWidth);
btn.setOnClickListener(this);
}
public void onClickWidth(View v)
{
if(v == btn){
//your code...
}
}
set the android:descendantFocusability attribute of the parent layout which contains the ListView to value blocksDescendants like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants"> ...</LinearLayout>

Categories

Resources