I am developing a drawing application where the user can also insert a text sticker with the text they want. For this, when the user selects the text sticker, an AlertDialog appears, where he types the text. When inserting the first text there are no problems. The problem arises when the user already has a sticker and is going to add a new one. When the sticker is added to the canvas, all other stickers disappear, leaving only the new one. However, if the user double-clicks on the new sticker, or once outside the new sticker and clicks inside, the stickers reappear in their proper locations.
I already did a test, where I generate sticker defaults with the same name outside the alertDialog, with just a press of any button, and the stickers are added correctly without the others disappearing. In other words, my stickers just don't work when I use alertDialog. I've already run and I can't find the error. Can someone help me?
MainActivity:
text.setOnClickListener {
showAlertDialogSticker()
}
//Change text color dialog box
private fun showAlertDialogSticker() {
val dialogBuilder = AlertDialog.Builder(this#MainActivity)
val layoutView = layoutInflater.inflate(R.layout.dialog_sticker, null)
checkBold = layoutView.findViewById(R.id.radio_bold)
checkItalic = layoutView.findViewById(R.id.radio_italic)
checkSublime = layoutView.findViewById(R.id.radio_sublime)
pickedColorSticker = layoutView.findViewById(R.id.pickedColorSticker)
txtSticker = layoutView.findViewById(R.id.txt_sticker)
sticker = layoutView.findViewById(R.id.sticker)
multiColorPickerSticker = layoutView.findViewById(R.id.multiColorPickerSticker)
multiColorPickerSticker.setInitialColor(0x7F313C93)
multiColorPickerSticker.subscribe { color: Int, _: Boolean, _: Boolean ->
pickedColorSticker.setBackgroundColor(color)
sticker.setTextColor(color)
textColor = color
}
dialogButtonCancel = layoutView.findViewById(R.id.btnCancel)
dialogButtonAdd = layoutView.findViewById(R.id.btnSave)
dialogBuilder.setView(layoutView)
dialogAdd = dialogBuilder.create()
dialogAdd.window?.attributes?.windowAnimations ?: R.style.DialogAnimation
dialogAdd.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialogAdd.show()
dialogButtonCancel.setOnClickListener {
dialogAdd.cancel()
}
dialogButtonAdd.setOnClickListener {
//Add text sticker
validFiel()
if (isValid) {
my_canvas.addTextSticker(textStick, textColor, null)
dialogAdd.dismiss()
}
}
}
Using the code above I have the problem reported. Calling the method as below, it was possible to add several stickers without problems.
text.setOnClickListener {
my_canvas.addTextSticker(textStick, textColor, null)
}
Related
So I am facing a weird bug I cannot explain - I cannot even reproduce it sometimes.
Basic context:
I have an application, which lists objects. Every object has a name and a point value. For every object, the addCustomSpinner function creates a "ticket" (a custom view, kind-of-spinner) and shows them in a scrollview so the user can select the one needed. There are four different 'containers' for four different kind of objects - so the layout can be populated with four kind of "ticket" package.
The data for the objects are collected from a database. The addCustomSpinner is called with a for cycle for every object in the database, and - Important - before the for method, the Layout it populates with the tickets is cleared (removeAllViews).
Inside addCustomSpinner, everything is created as "new" - like the button in question.
addCustomSpinner creates this button and adds a new onClickListener. Inside onClickListener, a new boolean is created - this is used to show a different animation when the button is clicked again. On first click (boolean = true), the arrow turns 180 degrees and faces upwards, on second click (boolean = false) the arrow turns 180 degrees and faces downwards. Works like a charm, until...
The bug I am facing:
Sometimes - as I already mentioned, not every time - if I click the button for one "ticket", then leave it 'opened' and click on an another one, and leave it 'opened' also, THEN I choose to populate the layout with a different kind of "ticket" package - The arrow faces upwards by default on every ticket in every package! Sometimes - again, just sometimes - with the same pattern I can turn it back, but it happens just "by accident".
I don't understand how the animation and state of the buttons can be connected, if every created ticket is new, every button is new, every onClickListener is new, and every boolean inside onClickListener is new. And if these are connected somehow, then why can that be that every behavior is "unique" for the buttons, nothing else shows any connection - even this is just a "sometimes" bug, a pretty rare one.
Can anybody help me why this happens?
What I tried:
Well, tried to trace the issue - but since it happens just by accident, I have no clue, I just searched if I can do anything else than the boolean to add different animation for the clicks. Sadly using ObjectAnimator is not a good solution for me - not the same result at least, since my animated arrow not only rotates, but it also changes its color. Shapeshifter seemed like a good idea to create animations easily, but now as I see it, maybe a simple rotation will be my ultimate solution.
Here's the code for the button:
customButton.setOnClickListener(new View.OnClickListener() {
boolean isCustomButtonClicked = true;
#Override
public void onClick(View v) {
if (isCustomButtonClicked) {
customButton.setImageResource(R.drawable.avd_anim_arrow_blue_back);
Drawable d = customButton.getDrawable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (d instanceof AnimatedVectorDrawable) {
animArrowAnim = (AnimatedVectorDrawable) d;
animArrowAnim.start();
}
}
routeWhoClimbed.setVisibility(View.VISIBLE);
isCustomButtonClicked = false;
} else if (!isCustomButtonClicked) {
customButton.setImageResource(R.drawable.avd_anim_arrow_blue);
Drawable d = customButton.getDrawable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (d instanceof AnimatedVectorDrawable) {
animArrowAnim = (AnimatedVectorDrawable) d;
animArrowAnim.start();
}
}
routeWhoClimbed.setVisibility(GONE);
isCustomButtonClicked = true;
}
}
});
EDIT:
The full addCustomSpinner():
private void addCustomSpinner(Routes mRouteItemToAdd, String placeName) {
//creating a new View for my custom layout created in xml
View customRoutesView = new View(this);
LinearLayout.LayoutParams customViewParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
customRoutesView.setLayoutParams(customViewParams);
customRoutesView = LayoutInflater.from(this).inflate(
R.layout.custom_view_layout, routeLayout, false
);
//Setting up the views inside the custom view
ImageView imageViewDiffImage = customRoutesView.findViewById(R.id.routeDiffImageView);
TextView textViewRouteName = customRoutesView.findViewById(R.id.routeNameTextView);
TextView textViewRouteDiff = customRoutesView.findViewById(R.id.routeDiffTextView);
ImageButton customButton = customRoutesView.findViewById(R.id.customButton);
RadioButton climberNameOne = customRoutesView.findViewById(R.id.climberNameOne);
RadioButton climberNameTwo = customRoutesView.findViewById(R.id.climberNameTwo);
Button climbedItButton = customRoutesView.findViewById(R.id.climbed_it_button);
RadioGroup climberNameRadioGroup = customRoutesView.findViewById(R.id.climberNameRadioGroup);
RadioGroup climbingStyleRadioGroup = customRoutesView.findViewById(R.id.styleNameRadioGroup);
RelativeLayout routeWhoClimbed = customRoutesView.findViewById(R.id.routeWhoClimbedRelativeLayout);
imageViewDiffImage.setImageResource(R.mipmap.muscle);
textViewRouteName.setText(mRouteItemToAdd.name);
textViewRouteDiff.setText("Difficulty: " + (int) mRouteItemToAdd.difficulty);
climberNameOne.setText(climberName1);
climberNameTwo.setText(climberName2);
routeWhoClimbed.setVisibility(GONE);
//Here comes the button with the animated image
customButton.setOnClickListener(new View.OnClickListener() {
boolean isCustomButtonClicked = true;
#Override
public void onClick(View v) {
if (isCustomButtonClicked) {
customButton.setImageResource(R.drawable.avd_anim_arrow_blue_back);
Drawable d = customButton.getDrawable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (d instanceof AnimatedVectorDrawable) {
animArrowAnim = (AnimatedVectorDrawable) d;
animArrowAnim.start();
}
}
routeWhoClimbed.setVisibility(View.VISIBLE);
isCustomButtonClicked = false;
} else if (!isCustomButtonClicked) {
customButton.setImageResource(R.drawable.avd_anim_arrow_blue);
Drawable d = customButton.getDrawable();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (d instanceof AnimatedVectorDrawable) {
animArrowAnim = (AnimatedVectorDrawable) d;
animArrowAnim.start();
}
}
routeWhoClimbed.setVisibility(GONE);
isCustomButtonClicked = true;
}
}
});
//Button, works like an 'OK' or something, and I have no
//problem with this
climbedItButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int checkedNameButton = climberNameRadioGroup.getCheckedRadioButtonId();
int checkedStyleButton = climbingStyleRadioGroup.getCheckedRadioButtonId();
RadioButton checkedNameRadioButton = (RadioButton) findViewById(checkedNameButton);
RadioButton checkedStyleRadioButton = (RadioButton) findViewById(checkedStyleButton);
String checkedName = (String) checkedNameRadioButton.getText();
String checkedStyle = (String) checkedStyleRadioButton.getText();
addClimbToDatabase(user.getUid(), checkedName, mRouteItemToAdd, placeName, checkedStyle);
}
});
//And finally, I add this new "ticket" with the custom view to the layout i want to show it. Again, this also works like a charm, no problem here.
routeLayout.addView(customRoutesView);
}
Ultimately, I did not manage to understand the problem throughly, but I was able to eliminate it.
So during my fixing tries I narrowed down the problem to the animated drawable state - credit to #avalerio for his pro tip, but the answer wasn't addig an id to the button. I think somehow and sometime, the state of the first animation (turning the arrow 180 degrees) stuck in the end position - causing the other views using this animatedDrawable showing it in end position on start.
.reset() did not help, since it resets the animatedVectorDrawable object, not the animation xml drawable state. My solution is a kind of workaround, but it is working: when the custom-view 'ticket' is created with the animated-drawable-imagebutton, I set the imageResource of the button to a not-animated xml drawable - this drawable is basically the start position of my animated-drawable. This way, when the 'tickets' are generated, the imagebutton is 'hardcoded' in the start position.
Not elegant, but works. BUT(!) I would really appreciate if someone could explain to me how this weird behavior is possible - just sometimes, randomly, with no pattern I can reproduce intentionally.
This is an often asked question but I just can't find the right solution for my case. I'm working on a news app and I want to fullscreen images in the news content when the user clicks the image, and another click will return to the news page. In my code, I have an ArrayList of data with the type of image or text, this method will go through the ArrayList and dynamically add an image view or text view according to the type. The code is like
public void setText(ArrayList<HashMap<String, String>> datas) {
for (HashMap<String, String> hashMap : datas) {
String type = hashMap.get("type");
if (type.equals("image")) {
int imagewidth = mTypedArray.getDimensionPixelOffset(R.styleable.customTextView_image_width, 100);
int imageheight = mTypedArray.getDimensionPixelOffset(R.styleable.customTextView_image_height, 100);
imageView = new ImageView(mContext);
params = new LayoutParams(imagewidth, imageheight);
params.gravity = Gravity.CENTER_HORIZONTAL;
imageView.setLayoutParams(params);
addView(imageView);
DownloadPicTask task = new DownloadPicTask(imageView, handler);
task.execute(hashMap.get("value"));
} else {
//Add some text view
}
I have tried simply changing the image to FIT_XY on click, but only the last spawned image enlarged, and I don't want other content to still remain around the image.
Perhaps I should set an onclick listener to each image, then create a new fullscreen activity? But I'm new to android and I don't know how to pass the image data correctly to fullscreen activity, and how to make another click back to the original content.
So, I dont know if I am missing something but any way I work it or look into it I am unable to click on any buttons on the screens.
I made a dialog box with a button essentially as shown in the sample projects but when ever I try to click the button nothing happens at all.
I tried firing the onClick programmatically and it works fine, I also tested that the mouse inputs were being registered okay and they were.
I am at a total loss for any reason why this wouldnt work.
My class code is below:
public class Interactable : UICanvas
{
public void interact()
{
var skin = Skin.createDefaultSkin();
var table = stage.addElement(new Table());
table.center();
table.setFillParent(true);
table.add(talk(this.entity.name, "Stay a while and glisten", "Bye!"));
}
public Dialog talk(string title, string messageText, string closeButtonText)
{
var skin = Skin.createDefaultSkin();
var style = new WindowStyle
{
background = new PrimitiveDrawable(new Color(50, 50, 50)),
//Dims the background
stageBackground = new PrimitiveDrawable(new Color(0, 0, 0, 150))
};
var dialog = new Dialog(title, style);
dialog.getTitleLabel().getStyle().background = new PrimitiveDrawable(new Color(55, 100, 100));
dialog.pad(20, 5, 5, 5);
dialog.addText(messageText);
var exitButton = new TextButton(closeButtonText, skin);
exitButton.onClicked += butt => dialog.hide();
dialog.add(exitButton);
return dialog;
}
}
}
The interact() is called when running up to another entity and pressing "E".
Which causes everything to render properly but I can't click on the button.
Additionally:
When i try to view exitButton co-ordinates theyre always 0 no matter what although the dialog appears in the middle of the window
Monogame version: 3.7
Nez version: 0.9.2
UPDATE:
So it seems like buttons are clickable but their click box is not even nearly aligning with where the buttons are truely rendered.
UPDATE2:
It seems that the issue is that where the button is being rendered and where the actual click box is are not the same.
I have Zoomed in the camera by 2 and the camera also follows my little character around. The dialog will then appear at the X,Y in relation to the current camera view but the actual click box appears at the X,Y in terms of the TiledMap (which is not always on screen).
Not too sure how to work around this.
So! The issue I was having was I was using one renderer for the entire this (The RenderLayerRenderer.) What I have done to fix this is start another renderer (A ScreenSpaceRenderer). This allows me to use it to render UI and its XY variables do not change but are just static to the visual area.
So i ended up with two renders like so:
addRenderer(new RenderLayerRenderer(0,new int[] { (int)RenderLayerIds.First, (int)RenderLayerIds.Second, (int)RenderLayerIds.Third}));
addRenderer(new ScreenSpaceRenderer(1, new int[] { (int)RenderLayerIds.UILayer }));
Using the first for my game rendering and the bottom on just for HUD things!
I'm trying to make a simple JDialog, which asks the user for input in the form of 3 text fields, and it displays correctly and its PropertyListener works perfectly fine, I haven't assigned a parent for the JDialog in it's constructor, so I'm guessing by default the parent is set to be the ancestor of all the components in my applet. However, when I change from the applet to, say a firefox window and when I click back on my applet, the JDialog has disappeared. Would I need to set a certain property to the JDialog to make sure it stays even when I switch windows. The starnge thing is that I think the dialog is still up, but invisible, because when another dialog appears after the first has disappeared, both dialog appear at once(the first dialog reappearing). MY code for the JDialog is just below:
private void addQuestion() {
questionTextField = new TextField(50);
Object[] componentsArray = {"Question:", questionTextField, "MQLYes:", mqlYesTextField, "MQLNo:", mqlNoTextField};
Object[] options = {"Enter", "Cancel"};
addQuestionDialog = new JDialog(new JFrame(),"Add question");
addQuestionPane = new JOptionPane(componentsArray, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]);
int x = getX() + getWidth()/2, y = getY() + getHeight()/2;
addQuestionDialog.setContentPane(addQuestionPane);
addQuestionDialog.setResizable(false);
addQuestionDialog.setSize(300,210);
addQuestionDialog.setVisible(true);
addQuestionDialog.setLocation(x, y);
addQuestionDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
addQuestionPane.addPropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (addQuestionDialog.isVisible() && (e.getSource() == addQuestionPane) && (JOptionPane.VALUE_PROPERTY.equals(prop) || JOptionPane.INPUT_VALUE_PROPERTY.equals(prop))) {
Object value = addQuestionPane.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
//ignore reset
return;
}
//Reset the JOptionPane's value.
//If you don't do this, then if the user
//presses the same button next time, no
//property change event will be fired.
addQuestionPane.setValue(
JOptionPane.UNINITIALIZED_VALUE);
if (value.equals("Enter")) {
String questionTypedText = questionTextField.getText();
String mqlYesTypedText = mqlYesTextField.getText();
String mqlNoTypedText = mqlNoTextField.getText();
sqlModel.addQuestion(questionTypedText, mqlYesTypedText, mqlNoTypedText);
questionTextField.setText("");
mqlYesTextField.setText("");
mqlNoTextField.setText("");
} else { //user closed dialog or clicked cancel
addQuestionDialog.setVisible(false);
}
}
}
I've checked the code several time and I don't see any issues with it, and the dialogs do what they're supposed to do, so I'm guessing there's a special addQuestion.set...(Object setValue) method which I should be adding in.
Would I need to set a certain property to the JDialog to make sure it stays even when I switch windows.
Yes.
I haven't assigned a parent for the JDialog in it's constructor,
and that would be the problem. The dialog will be visible whenever the owner of the dialog is visible, so you need to specify the owner JFrame.
i am trying to learn android keyboard api.
Using the softKeyboard example, i am trying to change the key icon, i can change everything, but the icon never change.
i am doing it in the LatinKeyboardView, at the onLongPress method, using this line:
copia.icon = getResources().getDrawable(R.drawable.tecladir);
but the icon doesn't change.
Even after using
this.invalidateAllKeys();
to force redraw of the keys, the icon is still unchanged.
Complete code of onLongPress as following:
#Override
protected boolean onLongPress(Key key) {
key.icon = getResources().getDrawable(R.drawable.tecladir);
//tecladir is one image i have
key.text = "batata";
key.label = "batata";
this.invalidateAllKeys();
//default code of method
if (key.codes[0] == Keyboard.KEYCODE_CANCEL) {
getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null);
return true;
} else {
return super.onLongPress(key);
}
}
Am i missing something?
Ok, found the solution.
before assign a new icon, the label must be null, otherwise the icon doesn't change, the correct way is:
key.label = null;
key.icon = getResources().getDrawable(R.drawable.tecladir);