Hi guys I can't figure out why I cant get it to work, to check the CheckBox of an activity from within another class.
In the onCreate method of the activity I'm passing a reference of itself to another class
public MainActivity()
...
dbi = new DBPrefsInterface(this);
...
}
public DBPrefsInterface(Context ctx)
{
MainActivity pma = (MainActivity)ctx;
this.ma = pma;
}
Now I try to Check a checkbox which is placed on the activity
this.ma.cbx.setChecked(true);
but it isn't working.
It seems I didn't pass a reference, only a Copy of MainActivity.
Thanks in adcance
Try passing a handler and a reference to the checkbox in the constructor of the other class
and make the handler send a message to the checkbox's original context
hanlder.post(new Runnable() {
#override
void run {
checkbox.setChecked(true);
}
});
Why don't you pass in the CheckBox itself? So your constructor becomes public DBPrefsInterface(CheckBox cbx) and you manipulate that reference.
Here is an example of a simple activity to demonstrate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.checkbox);
CheckBox cbx = (CheckBox) findViewById(R.id.box);
Button button = (Button) findViewById(R.id.button);
final DBPrefsInterface iface = new DBPrefsInterface(cbx);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
iface.toggle();
}
});
}
private class DBPrefsInterface {
CheckBox cbx = null;
public DBPrefsInterface(CheckBox cbx) {
this.cbx = cbx;
}
public void toggle() {
cbx.setChecked(cbx.isChecked());
}
}
I don't see why you would want to do this, but I think using the following constructor would do the work:
private MainActivity ma;
public DBPrefsInterface(MainActivity a){
ma = a;
}
Then to set the checkbox (but checkbox needs to be public in order to work):
ma.cbx.setChecked(true);
Related
I have created the customAdapter of ListView. when I click the Button in the ListView,I want to control the TextView outside the ListView from different layout. Notice ! There are not in the same Java code.
here is what I want to do:
viewHolder.plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TextView tx=(TextView) txt.findViewById(R.id.moneytext);
//find the textview outside listview (now In the same java code and xml)
totalmoney= (Integer.parseInt(tx.getText().toString()))+(Integer.parseInt(price[position]));
//get the textview integer and add to my present number
tx.setText(""+totalmoney);
//post on the textview
}
});
There is couple ways to do that I remember 3 of :
1) Add TextView to your ListView adapter constructor's parameters
2) Add your Activity to constructor
3) Use Event based solution like EventBus [This can be used even your TextView and ListView in different Activity and you don't need parameters]
There is example of 1 and 2:
public class YourListAdapter{
TextView strangerTextView;
YourActivity yourActivity;
public YourListAdapter(TextView strangerTextView,Activity yourActivity){
//using one of them is enough
this.strangerTextView=strangerTextView;
this.yourActivity=yourActivity;
}
//when changing text use like
strangerTextView.setText("Class Board");
//or (make sure you have global public textview attribute in your YourActivity class)
yourActivity.textview.setText("Class Board");
}
For EventBus :
1) Create a class that holds event information :
public class TextChangeEvent{
public String newtext;
public TextChangeEvent(String newtext){
this.newtext=newtext;
}
}
2) Then in your relevant Activity :
#Override
protected void onStart() {
super.onStart();
if(!EventBus.getDefault().isRegistered(this))EventBus.getDefault().register(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
#Subscribe
public void onEvent(TextChangeEvent event) {
this.textView.setText(event.newtext)
}
3) Post events like that, anywhere you want :
EventBus.getDefault().post(new TextChangeEvent("newtext"));
Are your TextView in the same activity? If yes, then you should put
tx = (TextView) findViewById(R.id.moneytext);
in onCreate() method and then access it from listener you have:
tx.setText("" + totalmoney);
If it is not in the same activity, you can make something like this:
public class ClassA extends Activity
{
public TextView textView;
public void onCreate()
{
super.onCreate();
textView = (TextView) findViewById(R.id.moneytext);
}
}
public class ClassB extends Activity
{
...
viewHolder.plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//classA is a global variable that you get for example from contructor
tx = classA.textView;
totalmoney= (Integer.parseInt(tx.getText().toString()))+(Integer.parseInt(price[position]));
//get the textview integer and add to my present number
tx.setText(""+totalmoney);
//post on the textview
}
});
...
}
In android, I have a custom layout I built:
public class ButtonMatch extends RelativeLayout
{
private final TextView text_round, text_match, text_player1, text_player2;
public ButtonMatch(final Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.button_match, this, true);
text_round = (TextView) findViewById(R.id.text_round);
text_match = (TextView) findViewById(R.id.text_match);
text_player1 = (TextView) findViewById(R.id.text_player1);
text_player2 = (TextView) findViewById(R.id.text_player2);
}
public void setRound(String text) {
text_round.setText(text);
}
public void setMatch(String text) {
text_match.setText(text);
}
public void setPlayer1(String text) {
text_player1.setText(text);
}
public void setPlayer2(String text) {
text_player2.setText(text);
}
public String getPlayer1() {
return text_player1.getText();
}
public String getPlayer2() {
return text_player2.getText();
}
}
Then I am adding this layout in code with the following:
ButtonMatch button = new ButtonMatch(this);
button.setLayoutParams(layout);
button.setTag(match.get("id"));
button.setMatch(match.get("identifier").toString());
button.setPlayer1(players.get(match.get("player1_id").toString()));
button.setPlayer2(players.get(match.get("player2_id").toString()));
button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
Intent intent = new Intent(view.getContext(), ChallongeMatch.class);
intent.putExtra(MainActivity.EXTRA_API_KEY, API_KEY);
intent.putExtra(MainActivity.EXTRA_SUBDOMAIN, SUBDOMAIN);
intent.putExtra(MainActivity.EXTRA_EVENT_ID, EVENT_ID);
intent.putExtra(MainActivity.EXTRA_MATCH_ID, view.getTag().toString());
intent.putExtra(MainActivity.EXTRA_PLAYER1, view.getPlayer1());
intent.putExtra(MainActivity.EXTRA_PLAYER2, view.getPlayer2());
}
});
What I am missing though, is in the Intent with the onClickListener, I am trying to get the contents of the text_player1 and text_player2 as follows:
intent.putExtra(MainActivity.EXTRA_PLAYER1, view.getPlayer1());
intent.putExtra(MainActivity.EXTRA_PLAYER2, view.getPlayer2());
The problem is those two functions don't work getPlayer1() and getPlayer2, because they dont exist in the view...
How do I get these two functions to work. I don't know a lot about Android/Java yet, so please be explain as much as you can.
You forgot casting view to ButtonMatch.
This is safe, because you set the click listener on the button object.
Change your code to
((ButtonMatch) view).getPlayer1()
to access the method on your object.
I am using an animation to slide a view to the top of the screen. The code for the animation is contained within a method called LoopAnimation() which is called from main.
public class MainActivity extends AppCompatActivity {
final View view = findViewById(R.id.view);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoopAnimation(view); \\ The animation loop method
}
This LoopAnimation() method uses a nested setOnClickListener to create an animation loop
public void LoopAnimation(View view){
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// starts the animation
view.animate().translationY(-100);
view.animate().setDuration(1500);
// reverses the animation
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do some job here
view.animate().translationY(100);
view.animate().setDuration(1500);
LoopAnimation(view); // Method calls itself
// to create loop effect
}
});
}
});
}
The problem is that I am getting a trivial error that I can't understand. Although I have declared view as global and final, I get this error in LoopAnimation()
Variable 'view' is accessed from within inner class, needs to be declared final.
You are using the variable view that is defined within your method's scope. Notice that your method's parameter is also called view so you are not actually using the global variable that you think you are using.
public void LoopAnimation(View view){
Edit: I've looked more into the way that you are trying to do this, and the approach isn't what I would do. Here is something more reasonable:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View view = findViewById(R.id.view);
view.setOnClickListener(new View.OnClickListener() {
private boolean _forwards = true;
#Override
public void onClick(View v) {
if (_forwards) {
// starts the animation
v.animate().translationY(-100);
v.animate().setDuration(1500);
_forwards = false;
} else {
// reverses the animation
v.animate().translationY(100);
v.animate().setDuration(1500);
_forwards = true;
}
}
}
}
}
I want to create by code an array of objects that are subclasses of Button.
public class MyButton extends Button {
private Context ctx;
private int status;
public MyButton(Context context) {
super(context);
ctx = context;
status = 0;
}
private click() {
status = 1;
// OTHER CODE THAT NEEDS TO STAY HERE
}
}
In the main activity I do this:
public class myActivity extends Activity {
private MyButton[] myButtons = new MyButton[100];
#Override
public onCreate(Bundle si) {
super.onCreate(si);
createButtons();
}
private void createButtons() {
for (int w=0; w<100; w++) {
myButtons[w] = new MyButton(myActivity.this);
myButtons[w].setOnClickListener(new View.onClickListener() {
public void onClick(View v) {
// ... (A)
}
});
}
}
}
Now I want the click() method inside MyButton to be run each time the button is clicked.
Seems obvious but it is not at my eyes.
If I make the click() method public and run it directly from (A), I get an error because myButtons[w].click() is not static and cannot be run from there.
In the meantime, I an not able to understand where to put the code in the MyButton class to intercept a click and run click() from there. Should I override onClick? Or should I override onClickListener? Or what else should I do?
How can I run click() whenever one of myButtons[] object is clicked?
Thanks for the help.
You can cast View v you got in listener to MyButton and call click on it:
private void createButtons() {
View.OnClickListener listener = new View.onClickListener() {
public void onClick(View v) {
((MyButton) v).click();
}
};
for (int w=0; w<100; w++) {
myButtons[w] = new MyButton(myActivity.this);
myButtons[w].setOnClickListener(listener);
}
}
you can add:
View.onClickListener onclick = new View.onClickListener() {
public void onClick(View v) {
((MyButton)v).click();
//since v should be instance of MyButton
}
};
to your Activity
then use:
myButtons[w].setOnClickListener(onclick);
//one instance of onclick is enough, there is no need to create it for every button
in createButtons()
but ... why, oh why array of buttons we have ListView in android ...
My Activity has multiple lists so I have defined MyClickListener as below:
My question is how I should instantiate this class:
MyClickListener mMyClickListener = new MyClickListener();
Or maybe it is better to instantiate inside the onCreate(Bundle) and just define above. Whats considered the better way? I don't want too much in onCreate() its already full of stuff. Any thoughts on the declaration and instatiation? Whats the best way?
private class MyClickListener implements OnClickListener
{
#Override
public void onClick(View view) {
}
}
I use same kind of class mechanism as you mentioned in the question.
this is the way i use,
public class myActivity extends Activity
{
private MyListener listener = null;
private Button cmdButton = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cmdButton = (Button) findViewById(R.id.cmdButton);
cmdButton.setOnClickListener(getListener());
}
// method to fetch the listener object
private MyListener getListener()
{
if (listener == null)
{
listener = new MyListener();
}
return listener;
}
private class MyListener implements Button.OnClickListener
{
public void onClick(View v)
{
}
}
}
Why are you instantiating a listener like that in the first place? Just create a new one when you assign it to your listView.
listView.setOnClickListener( new MyListener());