I have a dialog that triggers on EditText's context menu. Dialog sets the amount of red, green and blue of EditText. The problem is that runtime error occurs when I click positive button. Items above works fine, they set the color of text in EditText as it should, but rgbDialog don't.
I think that the problem occurs here:
etRed = (EditText)findViewById(R.id.etRed);
etGreen = (EditText)findViewById(R.id.etGreen);
etBlue = (EditText)findViewById(R.id.etBlue);
But I don't know how to initialize etRed, etGreen and etBlue right. I think that I should place something before findView like
etRed = (EditText)Dialog.findViewById(R.id.etRed);
But don't know what, because everything is happening in the same method (onContextItemSelected)
#Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.white:
temp.setTextColor(Color.WHITE);
break;
case R.id.red:
temp.setTextColor(Color.RED);
break;
case R.id.green:
temp.setTextColor(Color.GREEN);
break;
case R.id.rgb:
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("choose the amount of red green and blue");
LayoutInflater inflater = this.getLayoutInflater();
dialogBuilder.setView(inflater.inflate(R.layout.colors, null));
dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
etRed = (EditText)findViewById(R.id.etRed);
etGreen = (EditText)findViewById(R.id.etGreen);
etBlue = (EditText)findViewById(R.id.etBlue);
red=etRed.getText().toString();
green = etGreen.getText().toString();
blue = etBlue.getText().toString();
intRed = Integer.parseInt(red);
intGreen = Integer.parseInt(green);
intBlue = Integer.parseInt(blue);
temp.setTextColor(Color.rgb(intRed, intGreen, intBlue));
}
});
dialogBuilder.setNegativeButton("CANCEL", null);
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
break;
default:
break;
}
return super.onContextItemSelected(item);
}
EditText temp is set like this, and works fine for items above rgb
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context, menu);
temp = (EditText)findViewById(v.getId());
super.onCreateContextMenu(menu, v, menuInfo);
}
you can have something like below to call findViewById from correct layout:
View dialogView = inflater.inflate(R.layout.colors, null);
dialogBuilder.setView(dialogView );
and when you are calling findViewById in onClick you can have like:
etRed = (EditText)dialogView.findViewById(R.id.etRed);
etGreen = (EditText)dialogView.findViewById(R.id.etGreen);
etBlue = (EditText)dialogView.findViewById(R.id.etBlue);
Check if this helps.
Related
I am developing an app which has a text message interface (something like Facebook Messenger, Whatsapp, etc). I want to be able to change the background color of all the chat bubbles (a ListView of TextViews) sent by the user when they pick a new color (in a NavigationView).
However, with the current code that I have, I only am able to change the color after the EditText used to compose the message is clicked again. Or I am able to only edit the first bubble sent, but as soon as the color is changed.
Here's what I tried :
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected",currentTheme);
editor.apply();
chatAdapter.notifyDataSetChanged();
//the following changes only the first message sent
for(int i=0; i<chatAdapter.getCount(); i++){
ChatData message = chatMessageList.get(position);
TextView msg = activity.findViewById(R.id.text);
msg.setText(message.body);
msg.setBackgroundResource(R.drawable.user_color1);
}
}
});
ChatData is a custom Class that I created which looks like this :
public class ChatAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private ArrayList<ChatData> chatMessageList;
private Context mContext;
ChatAdapter(Activity activity, ArrayList<ChatData> list) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
...
}
Color drawable:
<corners
android:bottomRightRadius="5dp"
android:radius="40dp"/>
<gradient
android:angle="45"
android:endColor="#01f1fa"
android:startColor="#0189ff"
android:type="linear" />
</shape>
getView() method of the Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
ChatData message = chatMessageList.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.msglist, parent, false);
TextView msg = vi.findViewById(R.id.text);
msg.setText(message.body);
LinearLayout layout = vi.findViewById(R.id.message_layout);
LinearLayout parent_layout = vi.findViewById(R.id.message_layout_parent);
inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// if message is mine then align to right
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
int couleurBubble = getCouleurSelectionnee();
switch(couleurBubble){
case R.color.c1: msg.setBackgroundResource(R.drawable.user_color1); break;
case R.color.c2: msg.setBackgroundResource(R.drawable.user_color2); break;
case R.color.c3: msg.setBackgroundResource(R.drawable.user_color3); break;
case R.color.c4: msg.setBackgroundResource(R.drawable.user_color4); break;
case R.color.c5: msg.setBackgroundResource(R.drawable.user_color5); break;
case R.color.c6: msg.setBackgroundResource(R.drawable.user_color6); break;
case R.color.c7: msg.setBackgroundResource(R.drawable.user_color7); break;
case R.color.c8: msg.setBackgroundResource(R.drawable.user_color8); break;
default: break;
}
parent_layout.setGravity(Gravity.RIGHT);
}
// If not mine then align to left
else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
return vi;
}
I don't really know where to go from here so any kind of help would be appreciated. If you want me to provide more code, let me know and I will.
Thank you.
I'm sharing how I would do it. Maybe, this can help you.
There's some strange issue because you are calling notifyDataSetChanged(). This would be enough to re-draw all message bubbles.
My ideia is:
Add a int variable to the adapter class (mColorResource). This variable will point to the proper drawable that should be used (like R.drawable.user_color1).
public class ChatAdapter extends BaseAdapter {
int mColorResource;
ChatAdapter(Activity activity, ArrayList<ChatData> list, int initialColorResource) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// You must receive the color on the construtor
mColorResource = initialColor;
}
// Use this method to update the color (when user select a new color)
public void setColor(int newColorResource) {
mColorResource = newColorResource;
}
public View getView(int position, View convertView, ViewGroup parent) {
...
// Note how this if-else is cleaner now
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
msg.setBackgroundResource(mColorResource);
parent_layout.setGravity(Gravity.RIGHT);
} else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
...
}
}
Then, when a color is selected, find the proper drawable based on the view clicked and pass it to the adapter:
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected", currentTheme);
editor.apply();
// Here, you send the proper drawable...
// I'm not sure how you convert color selected to the drawable
// So, add your logic to convert the button clicked to a drawable here
// like R.drawable.user_color1
chatAdapter.setColor(R.drawable.NAME_OF_THE_COLOR);
// Request to re-draw all items from the list (all bubbles)
chatAdapter.notifyDataSetChanged();
}
});
Also, on your activity, you create the adapter with the last used color. Something like:
#Override
protected void onCreate(#Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
// Set a default color (if user is open you app for the first time)
int chatColor = R.drawable.user_color1;
// Add your logic to read the shared preference and convert that last color used to a valid drawable.
// Like chatColor = pref.getInt(indexColorSelected, R.drawable.user_color1) etc....
// Set the color in the adapter.
chatAdapter = newAdapter(this, mChatDataList, chatColor);
}
I am implementing a Drag and Drop interface with 6 Drag TextViews and 6 Drop TextViews.
Any 1 of 6 Drag views can be dropped onto any 1 of 6 Drop views.
An example would be if tvNum1=13, tvNum2=16, tvNum3=9, then I can drop any one of them onto tvSTR, tvDEX, or tvINT and set the respective Drop text to whatever was dragged. So if tvNum2 was dragged onto tvSTR, then tvSTR should show 16. Or let's say that instead you decided to drag tvNum3 onto tvSTR, then tvSTR should show 9. Each Drag view can only be used once.
Here's my current code. I can't find a way to make it so that the text of whatever was dragged is the text of the Drop view. I can only make (a 1-to-1 correlation) it so that if tvNum1 was dragged onto tvSTR, then tvSTR=13. Or if tvNum2 was dragged onto tvDEX, then tvDEX=16.
public class setCharacterRolls extends AppCompatActivity
{
// Variable declarations
private TextView tvNum1, tvNum2, tvNum3, tvNum4, tvNum5, tvNum6;
private TextView tvSTR, tvDEX, tvINT, tvWIS, tvCHA, tvCON;
String roll1, roll2, roll3, roll4, roll5, roll6;
// String roll1Num, roll2Num, roll3Num, roll4Num, roll5Num, roll6Num;
private Button bSubmit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_character_rolls);
// Get the previous intent
Intent intent = getIntent();
// Save the rolls from the previous screen onto a String to use later.
roll1 = intent.getStringExtra("roll1");
roll2 = intent.getStringExtra("roll2");
roll3 = intent.getStringExtra("roll3");
roll4 = intent.getStringExtra("roll4");
roll5 = intent.getStringExtra("roll5");
roll6 = intent.getStringExtra("roll6");
// Get TextView id's
tvNum1 = (TextView) findViewById(R.id.tDrag1);
tvNum2 = (TextView) findViewById(R.id.tDrag2);
tvNum3 = (TextView) findViewById(R.id.tDrag3);
tvNum4 = (TextView) findViewById(R.id.tDrag4);
tvNum5 = (TextView) findViewById(R.id.tDrag5);
tvNum6 = (TextView) findViewById(R.id.tDrag6);
tvSTR = (TextView) findViewById(R.id.tvSTR);
tvDEX = (TextView) findViewById(R.id.tvDEX);
tvINT = (TextView) findViewById(R.id.tvINT);
tvWIS = (TextView) findViewById(R.id.tvWIS);
tvCHA = (TextView) findViewById(R.id.tvCHA);
tvCON = (TextView) findViewById(R.id.tvCON);
// Set TextView to the roll numbers
tvNum1.setText(roll1);
tvNum2.setText(roll2);
tvNum3.setText(roll3);
tvNum4.setText(roll4);
tvNum5.setText(roll5);
tvNum6.setText(roll6);
// Set TextView to be draggable
tvNum1.setOnTouchListener(onTouch);
tvNum2.setOnTouchListener(onTouch);
tvNum3.setOnTouchListener(onTouch);
tvNum4.setOnTouchListener(onTouch);
tvNum5.setOnTouchListener(onTouch);
tvNum6.setOnTouchListener(onTouch);
// Targets to be dropped on
tvSTR.setOnDragListener(dragListener);
tvDEX.setOnDragListener(dragListener);
tvINT.setOnDragListener(dragListener);
tvWIS.setOnDragListener(dragListener);
tvCHA.setOnDragListener(dragListener);
tvCON.setOnDragListener(dragListener);
}
View.OnTouchListener onTouch = new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent mEvent)
{
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuild = new View.DragShadowBuilder(v);
v.startDrag(data, shadowBuild, v, 0);
return true;
}
};
View.OnDragListener dragListener = new View.OnDragListener()
{
#Override
public boolean onDrag(View v, DragEvent event)
{
int dragEvent = event.getAction();
switch(dragEvent)
{
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
final View view = (View) event.getLocalState();
switch(view.getId())
{
// This is where I have the 1-to-1 correlation.
// I want to be able to drag any draggable texview and set it to whatever it was dropped on.
case R.id.tDrag1:
tvSTR.setText(roll1);
break;
case R.id.tDrag2:
tvDEX.setText(roll2);
break;
default:
break;
}
break;
case DragEvent.ACTION_DROP:
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
default:
break;
}
return true;
}
};
}
I want to be able to respond to a click event on a disabled switch, is that possible?
I have a switch that is not enabled until the user fills in some information, so it looks like this:
I want to prompt the user to fill out the information if they click on the disabled switch with a dialog, like so:
mySwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!userInfo.isFilled){
new AlertDialog.Builder(MainActivity.this)
.setTitle("Fill out info first!")
.setMessage("You must first fill out info before turning on this featurel")
.setNeutralButton("Okay", null)
.show();
}
}
});
However, the onClick() is not triggered when I click on the disabled switch, so how do I get when the user clicks on it?
You could place a transparent View on top of the Switch and toggle its enabled state opposite the Switch, and show the message when this overlaid View is clicked.
From the View.java source code,
public boolean dispatchTouchEvent(MotionEvent event) {
// If the event should be handled by accessibility focus first.
if (event.isTargetAccessibilityFocus()) {
// We don't have focus or no virtual descendant has it, do not handle the event.
if (!isAccessibilityFocusedViewOrHost()) {
return false;
}
// We have focus and got the event, then use normal event dispatch.
event.setTargetAccessibilityFocus(false);
}
boolean result = false;
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}
final int actionMasked = event.getActionMasked();
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Defensive cleanup for new gesture
stopNestedScroll();
}
if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED
&& li.mOnTouchListener.onTouch(this, event)) {
result = true;
}
if (!result && onTouchEvent(event)) {
result = true;
}
}
if (!result && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
// Clean up after nested scrolls if this is the end of a gesture;
// also cancel it if we tried an ACTION_DOWN but we didn't want the rest
// of the gesture.
if (actionMasked == MotionEvent.ACTION_UP ||
actionMasked == MotionEvent.ACTION_CANCEL ||
(actionMasked == MotionEvent.ACTION_DOWN && !result)) {
stopNestedScroll();
}
return result;
}
the enabled flag ensures the UnhandledEvents are consumed however not passed along to the listeners,thereby bypassing all your possible code.So it is not possible to listen to events on a disabled view.
That said, your options are,
Change the style to mimic that of a disabled view as mentioned here,and then add your required functionality.
Add a overlay invisible view to perform your required functionality which you can set to Gone once the view should be enabled.
Use something apart from enabled,(you could setClickable(false) and consume touch events)
You can set onTouchListener and react to boolean (e.g isToggleEnable) reference with respect to the user's previous actions:
mySwitch.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if(!isToggleEnable){
//Taost here
}
//If isToggleEnable = false on return OnClickListener won't be called
return isToggleEnable;
}
});
When it is disabled, setEnabled(false), these listeners won't work.
Try this way: don't disable it, use the setOnCheckedChangeListener and check against your is-entry-filled in there:
use setOnCheckedChangeListener
switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!isEntryFilled) {
buttonView.setChecked(false);
// your alert dialog
} else {
}
}
});
this will re-check it back to off and pop your alert, until isEntryFilled is met.
EDIT
OR instead of setEnabled(false), use setClickable(false) or android:clickable="false" since docs say setClickable() is tied to click-events.
and instead of OnClickListener, try OnTouchListener. It will register your on-down-touch (and ignore your on-up-touch), since a click consists of down+up.
switch.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (!isEntryFilled) {
buttonView.setChecked(false);
// your alert dialog
}
return false;
}
});
then somewhere else, where you check for isEntryFilled, reactivate your switch with switch.setClickable(true)
Try setting setFocusable(false) and setEnabled(true) on your switch. That way, click events will be fired while the switch still being "disabled". Taken from this answer.
mySwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isClick()){
//Your Valid Code
}else{
//Make our switch to false
new AlertDialog.Builder(MainActivity.this)
.setTitle("Fill out info first!")
.setMessage("You must first fill out info before turning on this featurel")
.setNeutralButton("Okay", null)
.show();
}
}
});
public Boolean isClick(){
//check condition that user fill details or not
//if yes then return true
// else return false
}
Let the Parent View intercept ClickEvents or TouchEvents, when its detected check if the receiving View is disabled, and do what you have to do.
Edit
"it doesn't work when disabled?"
try these codes, Im use LinearLayout for easy aligment. but overall it should give you an example
this is a full example
XML
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
android:background="#273746">
<FrameLayout
android:layout_width="match_parent"
android:id="#+id/ass"
android:background="#drawable/abc_popup_background_mtrl_mult"
android:layout_height="match_parent">
</FrameLayout>
MainActivity onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entry_screen);
FrameLayout fl = (FrameLayout)findViewById(R.id.ass);
Test t = new Test(this);
FrameLayout.LayoutParams lp = (LayoutParams) fl.getLayoutParams();
lp.height = LayoutParams.MATCH_PARENT;
lp.width = LayoutParams.MATCH_PARENT;
t.setOrientation(LinearLayout.VERTICAL);
t.setLayoutParams(lp);
fl.addView(t);
t.setBackgroundColor(Color.YELLOW);
Button b = new Button(this);
b.setText("patricia");
t.addView(b);
b = new Button(this);
b.setText("monica");
t.addView(b);
b = new Button(this);
b.setText("rebecca");
t.addView(b);
}
Test.java
public class Test extends LinearLayout {
public Test(Context context) {
super(context);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
StringBuilder sb = new StringBuilder();
sb.append("intercept \n\r");
int x = (int)event.getX(),
y= (int)event.getY();
for(int i =0; i< getChildCount(); i++){
int[] pos = new int[]{getChildAt(i).getLeft(),getChildAt(i).getTop(),
getChildAt(i).getMeasuredWidth(),
getChildAt(i).getMeasuredHeight()};
sb.append(getChildAt(i).getLeft()+", ");
sb.append(getChildAt(i).getTop()+", ");
sb.append(getChildAt(i).getMeasuredWidth()+", ");
sb.append(getChildAt(i).getMeasuredHeight());
sb.append("\n\r");
sb.append(isInBounds(pos, x, y));
sb.append("\n\r");
}
sb.append("x is ");
sb.append(x);
sb.append("y is ");
sb.append(y);
Toast.makeText(getContext(),sb.toString() , Toast.LENGTH_LONG).show();
return super.onInterceptTouchEvent(event);
}
private boolean isInBounds(int[] dimen, int x, int y){
return ((x >= dimen[0] && x < (dimen[0] + dimen[2]))
&& (y >= dimen[1] && y < (dimen[1] + dimen[3])));
}
}
Now The one you click will check out to be true, that is the child, now when it checks out to be true you can do something like this
View v = getchildAt(pos);
//its the one that is tapped or clicked
if(!v.isEnabled()){
//this is the guy you want now, do what you want to do
for click event i am not try this, but you could just do View.performClick() or put your Dialog in the ViewGroup class and call it
actually you could use the View..getClipBounds() to save yourself from int array
Set the disable switches on click listener to change the listeners of the other switches. For example:
Switch s = (Switch) findViewById(R.id.SwitchID);
if (s != null) {
s.setOnCheckedChangeListener(this);
}
/* ... */
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Toast.makeText(this, "The Switch is " + (isChecked ? "on" : "off"),
Toast.LENGTH_SHORT).show();
if(isChecked) {
//do stuff when Switch is ON
//this is where you set your normal state OnClickListner
} else {
mySwitch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!userInfo.isFilled){
new AlertDialog.Builder(MainActivity.this)
.setTitle("Fill out info first!")
.setMessage("You must first fill out info before turning on this featurel")
.setNeutralButton("Okay", null)
.show();
}
}
});
}
}
I'm guessing you've disabled the switch using switch.setEnabled(false). If so, the onclick event will not trigger. If you still want to handle a click action when the switch is disabled, you can use .setOnTouchListener()...
You're best bet however would be to use .setOnCheckedChangeListener() and keeping the switch enabled. Basically when onCheckChanged() gets called, you can popup your dialog if the switch value is on and when the user click ok, you default the switch back to off.
mSwitched.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if (checked && !userInfo.isFilled){
new AlertDialog.Builder(Activity.this)
.setTitle("Fill out info first!")
.setMessage("You must first fill out info before turning on this featurel")
.setNeutralButton("Okay", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
mSwitched.setChecked(false);
}
})
.show();
}
}
});
You can do this in a different way,Give a root layout to toggle button with same width and height of toggle button
<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"
>
<!--Root layout to toggle button with same height and width
of toggle button-->
<LinearLayout
android:layout_width="wrap_content"
android:id="#+id/linear"
android:layout_height="wrap_content">
<ToggleButton
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
/>
</LinearLayout>
</RelativeLayout>
When you disable the button,make the button as not focasable and clickable .Then os will handover touch functionality to rootlayout.In the root layout click listner we can write the click logic when the button is not enabled
public class MainActivity extends AppCompatActivity {
ToggleButton button;
LinearLayout linearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (ToggleButton) findViewById(R.id.button);
linearLayout= (LinearLayout) findViewById(R.id.linear);
//disabling button
button.setEnabled(false);
button.setClickable(false);
button.setFocusableInTouchMode(false);
button.setFocusable(false);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//write the logic here which will execute when button is enabled
}
});
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//write the logic here which will execute when button is disabled
}
});
}
}
When you enable the button,make button to clickable and focausable.
//enabling button
button.setEnabled(true);
button.setClickable(true);
button.setFocusableInTouchMode(true);
button.setFocusable(true);
Hello im trying to use onclicklistener along with onmenuselectlistener in my mainactivity class and the program runs but selecting the popup menu opions dont work they wont set the text to want it want anyone have any idea's? I know i did not implement onMenuSelectListener and maybe thats my problem if it is is there any other way to makes this work?
Here is my code:
public class MainActivity extends Activity implements OnClickListener {
// init variables
Handler uiHandler;
EditText cl;
TextView info;
Button enter;
Button line;
Button arc;
DrawingUtils callDU = new DrawingUtils();
DrawingTools callDT = new DrawingTools();
EditTools callET = new EditTools();
Conversion callConversion = new Conversion();
GLSurfaceView mGLSurface;
String Tag = "Debug";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurface = new GLSurfaceView(this);
mGLSurface.setRenderer(new BasicRenderer());
setContentView(R.layout.canvas);
FrameLayout v = (FrameLayout) findViewById(R.id.canvas);
v.addView(mGLSurface);
// init views and buttons
info = (TextView) findViewById(R.id.info);
enter = (Button) findViewById(R.id.enter);
line = (Button) findViewById(R.id.line);
arc = (Button) findViewById(R.id.arc);
cl = (EditText) findViewById(R.id.cl);
/*
* Handler for Main Thread uiHandler = new Handler() { public void
* handleMessage(Message msg) { switch (msg.what) {
*
* } Bundle bundle = msg.getData(); String string1 =
* bundle.getString("P1Key"); String string2 =
* bundle.getString("P2Key"); info.setText(string1);
* info.setText(string2); } };
*/
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.enter:
break;
case R.id.line:
break;
case R.id.arc:
break;
}
};
public void CreatePopupMenu(View v) {
PopupMenu mypopupmenu = new PopupMenu(this, v);
MenuInflater inflater = mypopupmenu.getMenuInflater();
inflater.inflate(R.menu.filemenu, mypopupmenu.getMenu());
mypopupmenu.show();
}
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.newCanas:
info.setText("New");
Log.d(Tag, "New was clicked");
break;
case R.id.open:
break;
case R.id.save:
break;
}
return super.onMenuItemSelected(featureId, item);
}
}
It doesn't look like you're attaching onClickListeners to anything. What that means is you're saying "whenever the onClick event is fired with me as the target, perform this action". But then you're never making yourself a target. Try adding the following code to your onCreate.
arc.setOnClickListener(this);
line.setOnClickListener(this);
enter.setOnClickListener(this);
The same thing happens with the PopupMenu it appears. Try adding mypopupmenu.addOnMenuItemSelectListener(this) right after you inflate the layout for your menu.
Jonathan is right. You should add .setOnClickListener(this); to each of the buttons added after you create them.
For the menu items though, you have to do the following:
1) Create a layout with the items on your menu and store it in your res/menu/ directory.
Example:
main.xml
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="never"
android:title="#string/action_settings"/>
</menu>
2) Override the method called: onCreateOptionsMenu() to populate the items in the menu.
Example:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
3) Override the method onOptionsItemSelected() to do whatever you want with a switch like you were doing with the actionListeners.
4) Additionally, you could also override the method onPrepareOptionsMenu() which is the same as the previous one, but it is called every time the menu opens.
Good luck
I've been working at this all day, and I'm really close but just can't get this to work. I have a button that pulls up an AlertDialog populated with saved entries that include Name and Price. Right now, I can click an item in the Dialog and have it automatically fill in the Name and Price fields in my activity. I want to also be able to long press an item and receive an option to delete it. This is my first try at an Android app, and a lot of this is repurposed from the Notepad Tutorial. Two things I can't figure out:
1) Is my registerForContextMenu sufficient/correct?
2) What am I doing wrong with my onCreateContextMenu?
Thanks.
savedItems.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cDbHelper.open();
mNotesCursor = cDbHelper.fetchAllSaved();
startManagingCursor(mNotesCursor);
// Create an array of names and corresponding prices from db
String[] from = new String[]{SavedItemsDbAdapter.KEY_NAME, SavedItemsDbAdapter.KEY_PRICE};
// and an array of the fields we want to bind those fields to
int[] to = new int[]{R.id.text1, R.id.text2};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter saved =
new SimpleCursorAdapter(NewEntry.this, R.layout.saved_row, mNotesCursor, from, to);
// Build an AlertDialog to hold this list
AlertDialog.Builder builder = new AlertDialog.Builder(NewEntry.this);
builder.setTitle("Choose from list");
// IS THIS SUFFICIENT TO REGISTER FOR CONTEXT MENU?
registerForContextMenu(v);
builder.setAdapter(saved, new DialogInterface.OnClickListener() {
// When an item from the list is clicked, it automatically populates the name and price fields in activity
#Override
public void onClick(DialogInterface dialog, int item) {
Cursor c = mNotesCursor;
c.moveToPosition(item);
Intent i = new Intent(NewEntry.this, NewEntry.class);
i.putExtra("name", c.getString(
c.getColumnIndexOrThrow(SavedItemsDbAdapter.KEY_NAME)));
i.putExtra("price", c.getString(
c.getColumnIndexOrThrow(SavedItemsDbAdapter.KEY_PRICE)));
startActivityForResult(i, ACTIVITY_AUTO);
finish();
}
// TRYING AND FAILING TO SET UP A CONTEXT MENU - the goal is to be able to long press,
// have a "Delete?" option pop up, which will delete the entry when clicked
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteItem(info.id);
return true;
}
return false;
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
I just found
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
to be called, but not
#Override
public boolean onContextItemSelected(MenuItem item) {
in my subclassed AlertDialog:
public class MyAlertDialog extends AlertDialog implements
OnCreateContextMenuListener {
Perhaps this is useful to someone else as I'm pretty sure you have meanwhile solved your problem at hand.
You only need implement the following function. It will work.
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
Log.e(LOGTAG, "Tao menu");
if(v == expList)
{
super.onCreateContextMenu(menu, v, menuInfo);
//AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
//HashMap map = (HashMap) simpleAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options");
menu.add(1, 1, 1, "Reprint");
menu.add(1, 2, 1, "Void");
menu.getItem(0).setOnMenuItemClickListener(new OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem clickedItem)
{
return true;
}
});
menu.getItem(1).setOnMenuItemClickListener(new OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem clickedItem)
{
return true;
}
});
}
}
Is my registerForContextMenu sufficient/correct?
You are registering a context menu for whatever savedItems is. If that is what you want the context menu on, then you are OK.
If your goal is to have a context menu on the items in the list in the dialog, your approach is wrong. You will not be able to use AlertDialog.Builder. You will need to create a custom subclass of AlertDialog, so you can override onCreateContextMenu() there.