Why is ImageButton (Android - Java) not implementing onClick on actual image - java

I have not found a clear answer on this so I figured I would write a post to see if anybody can point me in the right direction.
Basically I am creating a Voice Notes application and I have set a 'delete' button for the locally saved files as a trash can image for an ImageButton. Seeing as users will be able to save as many audio files as they want I implemented a loop where the button is created, the ID is set via setID, and then a click listener is used based on the generated ID.
My problem is that the click listener works on the sides of the image, but not on the actual image, meaning if I click to the right or left of the ImageButton the file is deleted, however, when I actually click the trash can image in the ImageButton, nothing happens. I also have logs being registered anytime the button is clicked and they also don't work when I click the actual image, so I am sure the issue is that somehow the listener is not being used when the ImageButton is clicked. - Please remember that I said the click registers to the right and left of the image.
Here is the relevant code:
try{
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
//Button button = new Button(getApplicationContext());
TextView fileButton = new TextView(getApplicationContext());
fileButton.setTextColor(Color.parseColor("#ffffff"));
fileButton.setBackgroundResource(R.drawable.textview_button_colors);
fileButton.setTypeface(fileButton.getTypeface(), Typeface.BOLD);
fileButton.setText((i+1)+") "+listOfFiles[i].getName());
fileButton.setId(i);
fileButton.setPadding(10,10,10,10);//LTRB
fileButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButton = (RelativeLayout) inflater.inflate(R.layout.image_buttons, null);
deleteButton.setId(i+i);
Log.d(LOG_TAG, String.valueOf(deleteButton.getId()) );//WORKS AS EXPECTED
deleteButton.setGravity(Gravity.CENTER_HORIZONTAL);
TableRow horizontalButtonTableRow= new TableRow(getApplicationContext());
TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams
(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.WRAP_CONTENT);
int leftMargin=0;int topMargin=15;int rightMargin=0;int bottomMargin=0;
tableRowParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
horizontalButtonTableRow.setLayoutParams(tableRowParams);
horizontalButtonTableRow.addView(fileButton);
horizontalButtonTableRow.addView(deleteButton);
final String fileName = saveDirectory.toString() + File.separator +
listOfFiles[i].getName();
fileButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Log.d(LOG_TAG, "should be playing audio");
MediaPlayer mediaPlayer = new MediaPlayer();
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
FileInputStream fis = new FileInputStream(fileName);
mediaPlayer.setDataSource(fis.getFD());
Log.d(LOG_TAG, fileName);
mediaPlayer.prepare();
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
mediaPlayer.start();
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
Vibrator vib = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
vib.vibrate(25);
File deleteFile = new File(fileName);
deleteFile.delete();
savedFileLoader();
Log.d(LOG_TAG, fileName+": WAS DELETED");
} catch (Exception e) {
Log.d(LOG_TAG, String.valueOf(e));
}
}
});
verticalButtonContainerLayout.addView(horizontalButtonTableRow);
}//END IF
}//END FOR
}catch(Exception e){
Log.d(LOG_TAG,e.toString());
}
MORE INFO(but not used in final solution): If I change my code for the inflater to work like this the imageButton is no longer added to my view. I think this happens because I am forced to remove the image button from the original relative view.
LayoutInflater inflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout deleteButtonLayout = (RelativeLayout)
inflater.inflate(R.layout.image_buttons, null);
ImageButton deleteButton =
deleteButtonLayout.findViewById(R.id.imageButton);
deleteButtonLayout.removeView(deleteButton);
deleteButton.setId(i+i);
If I opt not to use removeView I get this exception:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Here is XML for imageButton in relative layout:
UPDATE: I have corrected my code based on the approved answer provided by #John Tribe. The "fix" was to set the RelativeLayout to clickable and at the same time setting the ImageButton to not be clickable. Doing this allowed my entire inflated layout to be clickable, which is exactly what I needed for this problem seeing as there was only 1 element in my inflated RelativeLayout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:clickable="true"
android:layout_height="match_parent">
<ImageButton
style="?android:attr/buttonBarStyle"
android:id="#+id/imageButton"
android:layout_width="30dp"
android:layout_height="30dp"
android:adjustViewBounds="true"
android:clickable="false"
android:scaleType="center"
android:background="#drawable/trash"/>
</RelativeLayout>

You used RelativeLayout , You should use Image or ImageButton,but if you really want to use RelativeLayout , then in xml add android:clickable="true".
Another approach can be by finding ImageButton and setting listener.
ImageButton deleteButton = deleteButtonLayout.findViewById(R.id.imageButton);
deleteButton.setOnClickListener( new On...);

Related

I want to create a checkbox when button is clicked

I want to make it so that every time someone types something in the editText and clicks the button, the text comes up. It does it in my code, but I also want to add a checkbox next to it. How can I add the checkbox every time the button is pressed?
This is how it looks in the emulator right now after I typed test in the editText:
https://gyazo.com/6b9a050976ecd2c4b509220263bbdce1
The second problem is: when I write a second todo, it overwrites the last one so right now I can only have 1 todo. Why?
Code:
final TextView textViewPrint;
Button btn_print;
final EditText editTextType;
textViewPrint = findViewById(R.id.print_text);
btn_print = findViewById(R.id.button_add);
editTextType = findViewById(R.id.test_textEdit);
btn_print.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
textViewPrint.setText(editTextType.getText().toString()) ;
editTextType.setText("");
}
});
You can add to your layout programmatically after it has been inflated. Add an id to your LinearLayout:
android:id ="#+id/layout"
Then in OnCreate (after your existing code), get a reference to it and add controls as you wish. And add these lines in OnCreate, For example:
LinearLayout l = (LinearLayout)findViewById(R.id.layout);
CheckBox cb = new CheckBox(this);
int lHeight = LinearLayout.LayoutParams.MATCH_PARENT;
int lWidth = LinearLayout.LayoutParams.WRAP_CONTENT;
l.addView(cb, new LinearLayout.LayoutParams(lHeight, lWidth));
setContentView(l);
First You need add to LinearLayout layout
LinearLayout l = (LinearLayout)findViewById(R.id.layout);
btn_print.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox cb = new CheckBox(this);
LayoutParams lparams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
cb.setLayoutParams(lparams);
l.addView(cb);
}
});

Adding button in runtime using button onclick event

I'm making a game in where the platform will add new button in each level the user has cleared. but I cant add new xml tag in the project on runtime. I'm a little lost of what to use or how to implement.
run = (Button)findViewById(R.id.btnRunChallengeMode);
run.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newForm = new Intent(Form2.this,Form2.class);
buttonPanel = (LinearLayout)findViewById(R.id.LinearButtonPanel);
Button newButton = new Button(null);
newButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
newButton.setId(a);
newButton.setText("Button " + a);
buttonPanel.addView(newButton);
a++;
startActivity(newForm);
}
});
below is the xml code
<HorizontalScrollView
android:id="#+id/buttonPanelChallengeMode"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_below="#+id/IDE"
android:layout_marginBottom="3dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/LinearButtonPanel">
</LinearLayout>
</HorizontalScrollView>
This is because after adding the button to the layout you are starting the new Activity no matter it's the same activity. Whenever activity is created it will always use the initial xml format. I think you are under the impression that adding new button will persist and becomes a part of XML. That's not true, if you want to start the new activity. Set new Button value in Bundle, then in onCreate check the existence of bundle. If exist's then add a new button.
int buttonId = -1;
protected void onCreate(Bundle b){
//set the layout related stuff first
Bundle b = getIntent().getExtras();
if(b!= null && (b.getInt(NEW_BUTTON_KEY, -1)!=-1)){
buttonPanel = (LinearLayout)findViewById(R.id.LinearButtonPanel);
for(int i = 0; i< b.getInt(NEW_BUTTON_KEY, -1); i++)
Button newButton = new Button(this);
newButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
newButton.setId(i);
newButton.setText("Button " + i);
buttonPanel.addView(newButton);
}
}
By the way why are you making new activity? Just add the button in the same activity, otherwise your activity stack will become massic with every level.
Button newButton = new Button(null);
You give to the context null, i suggest you to give proper context. Also you can set tag for button with newButton.setTag(value)
Your Code is not true
you create a button and add to a LinearLayout and after that you call startActivity for load an Activity. So You reset the LinearLayout and buttons clear from that.
you should :
run = (Button)findViewById(R.id.btnRunChallengeMode);
run.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newForm = new Intent(Form2.this,Form2.class);
newForm.putExtra("a", a);
startActivity(newForm);
}
});
and in the create , get Extras :
String a = getIntent().getIntExtra("a");
now you can create the button.

Adding textviews on button click android?

I've got a button that inserts user information into a database.
On top of this, I would like it to display the users entered details below in a list,
#Override
public void onClick(View v) {
insertuser();
LinearLayout createworkout = (LinearLayout)findViewById(R.id.createworkout);
TextView x = new TextView(getApplicationContext());
x.setText(editTextExercise.toString());
createworkout.addView(x);
}
This is what I have so far. When clicking the button the information is inserted, but I can not see a visible Textview. No errors are thrown either, I don't know what I have done wrong here.
All help appreciated
Thank you
Have your LinearLayout orientation property set?
try to add:
android:orientation="vertical"
or:
android:orientation="horizontal"
Try to change it as...
#Override
public void onClick(View v) {
insertuser();
LinearLayout createworkout = (LinearLayout)findViewById(R.id.createworkout);
TextView x = new TextView(YourActivity.this);
x.setText(editTextExercise.toString());
LayoutParams lp = new LayoutParams ( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
createworkout.addView(x,lp);
}

How to dim the background behind my pop up menu after clicking a button?

How do I get the background behind my pop up menu to dim after I click the button that opens the popup menu? Looked at other code samples but no luck! Would really appreciate any advice!
final Button Bel = (Button) findViewById(R.id.btnBel);
final ImageView Phone = (ImageView)findViewById(R.id.imgPhone);
relativeLayout = (RelativeLayout) findViewById(R.id.relative);
Bel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bel.setVisibility(View.GONE);
Phone.setVisibility(View.GONE);
layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup container = (ViewGroup) layoutInflater.inflate(R.layout.popup_menu, null);
popupWindow = new PopupWindow(container, 1000, 850, true);
popupWindow.showAtLocation(relativeLayout, Gravity.NO_GRAVITY, 221, 4000);
btnBelNuCall = (Button) container.findViewById(R.id.btnBelNu);
btnClosePopUp = (Button) container.findViewById(R.id.btnAnnuleren);
btnBelNuCall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:0900-33-44-55-6"));
startActivity(callIntent);
checkPermission();
}
});
btnClosePopUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
Bel.setVisibility(View.VISIBLE);
Phone.setVisibility(View.VISIBLE);
}
});
}
});
1. Create A Layout That Covers Everything In Your Main Layout
I don't know what your XML File looks like, but put something like this at the top of it:
<LinearLayout android:id="dim_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#70000000"
android:visibility="invisible"/>
Note: Depending on your XML file, you may need to alter this for it to be placed on top of all other components.
This will create a layout covering everything in your main layout with a background of color #70000000 which is black with an alpha level of 70. Changing the 70 at the beginning of the hex code will allow you to modify how transparent you want it to be.
2. Show Layout When Popup Is Activated
LinearLayout dim_layout = (LinearLayout) findViewById(R.id.dim_layout);
popupWindow = new PopupWindow(container, 1000, 850, true);
dim_layout.setVisibility(View.VISIBLE);
popupWindow.showAtLocation(relativeLayout, Gravity.NO_GRAVITY, 221, 4000);
3. Hide Layout When Popup Is Deactivated
btnClosePopUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
Bel.setVisibility(View.VISIBLE);
Phone.setVisibility(View.VISIBLE);
dim_layout.setVisibility(View.INVISIBLE);
}
});
Give an Id to your root tag and in your class, give it the dim background color. For example in your layout activity
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#F4F4F4"
android:orientation="vertical"
android:id="#+id/main_screen">
in your class
mainView = findViewById(R.id.main_screen);
mainView.setBackgroundColor(Color.parseColor("#30000000"));

ImageButton changing an Image of another ImageButton causes unintended cycle

Aftermath of this: Image for ImageButton doesn't change as intended
When ImageButton of "ibChamp" is clicked, it opens up champions.xml. In that layout, there is an Imagebutton called "ibAnnie". What I want that to do when clicked is, to change the image of "ibChamp", and to switch to that layout. What happened here is that after "ibAnnie" is clicked, it switches to "create_build_page.xml", and in that is a changed picture of "ibChamp". But that only happens for a split second before changing back to the original, unchanged picture, "create_build_page.xml" layout. When I click the back button, it goes to the "create_build_page.xml" layout with the changed picture, but the buttons do not work. I would gladly provide any additional information required.
I'm still not entirely clear on what you're trying to achieve... but if my understanding is correct, this should get you closer:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.champions);
ImageButton ibAnnie = (ImageButton) findViewById(R.id.ibAnnie);
ibAnnie.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
RelativeLayout test = (RelativeLayout) findViewById(R.id.layoutChampions);
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View createView = layoutInflater.inflate(R.layout.create_build_page, null);
test.addView(createView);
ImageButton img = (ImageButton) view.findViewById(R.id.ibChamp);
img.setImageResource(R.drawable.ic_launcher);
img.setTag(R.drawable.ic_launcher); // so you can retrieve it later
img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// this will set the imageView of ibAnnie
ibAnnie.setImageView((Integer)view.getTag());
// this will remove the selection view from your layout
((RelativeLayout) findViewById(R.id.layoutChampions)).removeChild(createView);
}
});
// this opens another Activity... you don't want that, at least not for what you seem to be trying to do.
/*try {
Intent open = new Intent("android.intent.action.CREATE");
startActivity(open);
} catch (Exception e) {
}*/
}
});
}

Categories