In my Activity I have one ImageView
XML Code:
<!-- FOTO LATERAL! -->
<ImageView
android:id="#+id/simbolo_raca"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<Button
android:id="#+id/button_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Ok. Seguinte Pergunta"
android:layout_gravity="right"
android:gravity="right"
android:paddingRight="30dip">
</LinearLayout>
This is the Activity:
public class QuestionarioActivityRaca extends Activity{
ImageView simbolo;
int position;
Button B_Save;
List<Drawable> List_imagens = new ArrayList<Drawable>();
#Override
public void onCreate(Bundle savedInstanceState) {
simbolo = (ImageView) findViewById(R.id.simbolo_raca);
B_Save = (Button) findViewById(R.id.button_save);
position = 0;
List_imagens.add(getResources().getDrawable(R.drawable.p1));
List_imagens.add(getResources().getDrawable(R.drawable.p2));
List_imagens.add(getResources().getDrawable(R.drawable.p3));
List_imagens.add(getResources().getDrawable(R.drawable.p4));
loadNewImage(position);
B_Save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
loadNewImage(position);
position++;
}
});
}
// I Use this method to load the Image
public loadNewImage(int Page)
{
new Thread(new Runnable(){
#Override
public void run(){
simbolo.post(new Runnable(){
#Override
public void run()
{
simbolo.setImageDrawable(List_imagens.get(Page));
}
});
}
}).start();
}
The first time I call this method, (position = 0) the image doesnt loads. After that, the image is loading correctly.
How I have to do to load the image the first time?
(I can not load the image in the XML using android:src="#drawable/x") because the image could be different anytime.
EDITED!
There are a number of issues with the code sample you posted.
like writing int with a capital I.
Int position;
Not sending in a parameter with your method in the onClick:
public void onClick(View v) {
loadNewImage();
}
And several more in both your XML and code.
Is there a spesific reason you want to run a new thread every time for this task?
If you really need a thread, you have to declare your int as final in the method.
However, you should get your desired result with the code-sample below.
You have to modify your onClick to send the appropriate int for whatever drawable you want to use.
Good luck.
public class testactivity extends ActionBarActivity {
ImageView simbolo;
int position;
Button B_Save;
List<Drawable> List_imagens = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testactivity);
simbolo = (ImageView) findViewById(R.id.simbolo_raca);
B_Save = (Button) findViewById(R.id.button_save);
position = 0;
List_imagens.add(getResources().getDrawable(R.drawable.ic_drawer));
List_imagens.add(getResources().getDrawable(R.drawable.ic_check));
List_imagens.add(getResources().getDrawable(R.drawable.ic_action_add_package));
List_imagens.add(getResources().getDrawable(R.drawable.ic_action_exception));
loadNewImage(position);
final Random rand = new Random();
B_Save.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
loadNewImage(rand.nextInt(4));
}
});
}
public void loadNewImage(final int page)
{
simbolo.setImageDrawable(List_imagens.get(page));
}
}
first of all before the button gets clicked you call this function to load the initial image with loadNewImage(position); when the button is clicked you call this function loadNewImage(); i am guessing it works when the button is clicked because this loadNewImage(); method is ok and loadNewImage(int page); is not ok, because they are two different function.
Solving your problem if you want an integer object use Integer position or else go with int position and please let go of the thread. now your code will work
Related
I have an ImageButton in my application.
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="80dp"
android:layout_height="80dp"
android:clickable="true"
android:src="#drawable/button" />
I bind it to an onClickListener:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
// Here I update the image source to a different image.
}
};
Now what happens is: when I click the imagebutton, the imagebutton changes to a
different image. But I want it to change back automatically after 0.5 sec (during the
same time the user should not be able to click anything). How do I
implement that? I tried to sleep in the onClick function in the listener, but it's
not working...
New edit:
The proposed answer will solve my problem if I only have one imagebutton. I tried it out
and both work like charm!
Actually it is not working as expected. During that 500ms, the user still could click!
It is not solving the problem...
Posting a delayed runnable might do the job.
public void onClick(View v) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
(ImageButton)v.setBackgroundResource(R.drawable.someimage);
}
}, 500);
}
EDIT:
In fact, I've ran the following code on an actual device with two ImageButton and it works fine.
BTW, if you want the buttons to be un-clickable during the 500ms, just set it as imgBtn1.setClickable(false); and set it back to be clickable in the runnable as imgBtn1.setClickable(true);
public class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test_layout, container, false);
final ImageButton imgBtn1 = (ImageButton) view.findViewById(R.id.test_img_btn1);
final ImageButton imgBtn2 = (ImageButton) view.findViewById(R.id.test_img_btn2);
imgBtn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn1.setBackgroundResource(R.drawable.device_type_apple);
imgBtn1.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn1.setBackgroundResource(R.drawable.device_type_windows);
imgBtn1.setClickable(true);
}
}, 500);
}
});
imgBtn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imgBtn2.setBackgroundResource(R.drawable.device_type_apple);
imgBtn2.setClickable(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// change the background of the image button
imgBtn2.setBackgroundResource(R.drawable.device_type_android);
imgBtn2.setClickable(true);
}
}, 500);
}
});
return view;
}
}
You can use handle with runnable to auto update image
Handler mHandler = new Handler();
Runnable mUpdateTimer = new Runnable() {
#Override
public void run() {
// code update image here
// auto update after 0.5s
mHandler.postDelayed(mUpdateTimer, 500);
}
};
And when image button clicked:
View.OnClickListener imgButtonHandler = new View.OnClickListener() {
public void onClick(View v) {
mHandler.postDelayed(mUpdateTimer, 500);
}
};
Handler.postDelayed
this method is not good way ,see http://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable,long)
it say
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
so this methed may never invoke,it may be make you image button status never come back ,so you must be care the return value or use other widget ViewFliper,it can set animation when image switch and you can set delpoy .
image123(ImageView) works normal but when it comes to ONclickListener it does not work even after using different methods of Calling the listener.
I put func(),which contain findviewbyid of image123 (ImageView) just after SetContentView() and it works fine .OnclickListener of image123 does not works when func() is in OnClicklistener of Reset Button as Shown in the Code.
Problem:
How can i call the func() in reset button onclicklistener as well as in start at Oncreate() Activity?
It catch an exception shown in Log cat
- Exception at Onclick Listener" ,"java.lang.NullPointerException
public class MainActivity extends Activity {
ImageView image123;
int[] resultid=new int[25];
Button buttonExit;
Button buttonreset;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonreset=(Button) findViewById(R.id.button_reset);
buttonExit=(Button) findViewById(R.id.button_exit);
v1=(TextView)findViewById(R.id.name);
v2=(TextView)findViewById(R.id.fruit_count);
//--------------------------Exit Button---------------------------
buttonExit.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
//*******************Exception comes here*********************
try{
image123.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.d("Listner Called", "Listner Called");
}
});
}
catch(Exception e)
{
Log.d("Exception at onclickListener", e.toString());
}
buttonreset.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
func();
}});
}
void func()
{
String as=null;
int resultid;
SecureRandom random=new SecureRandom();
image123=new ImageView(this);
as=("img"+1).toString();
resultid=getResources().getIdentifier(as, "id","com.example.selectiongame" );
Log.d(as, ""+resultid);
image123=(ImageView) findViewById(resultid);
as="drawable"+(random.nextInt(3)+1);
resultid = getResources().getIdentifier(as, "drawable", "com.example.selectiongame");
Log.d(as, ""+resultid);
image123.setImageResource(resultid);
}
Try creating an array of ResIDs and an array of ImageViews. Then do something like this instead of initializing them with findViewById()...
for(int i = 0; i < res_arr.length; i++)
{
images[i] = new ImageView(this);
images[i].setImageResource(res_arr[i]);
images[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d("Button_Clicked", "Button Clicked");
}
});
}
You must not findviewbyid() of an ImageView in some other function other than Oncreate(Bundle b) or Some Listener(e.g OnclickListener ,onselectionchange etc) . if you want to findviewbyid(...) of a view in a function other than Oncreate ,Atleast Call that function once after SetContentView() and other prerequisite Findviewbyid(...).
2.
In order to Refresh your Activity ,when you can not use function containing findviewbyid(...) of ImageView,like in my case, in body some button(e.g Refresh ,Reset) OnclickListner .You must write the following code
buttonreset.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Bundle newBundle=new Bundle();
onCreate(newBundle);
//func(); >>We can not use this func() here if we are using it in Oncreate(...) in case of Array of ImageView
}});
}
For views other than Imageview ,Maybe Regular Line of Code work ...But in case of ImageView or Array of ImageView ....These things must be kept in mind and Simply Oncreate() must be used to Refresh.
I have written an application that is designed to show report. The first screen of the application is a table that shows info (name, path) of the reports.
So I want to make the row of the table clickable in order to take me to the next screen where the detailed info of the report is displayed, and to know what is the corresponding report for the row. So I wrote my own row:
TableReportRow:
public class TableReportRow extends TableRow {
Report report;
public TableReportRow(Context context, Report report) {
super(context);
this.report = report;
}
public Report getReport() {
return report;
}
public void setReport(Report report) {
this.report = report;
}
}
And then I created the table programmatically:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reports_list_activity_layout);
application = (SGRaportManagerAppObj)getApplication();
reportsRepository = application.reportsRepository.getReportsRepository();
TableLayout table = (TableLayout) findViewById(R.id.tableReportsList);
table.setStretchAllColumns(true);
table.setShrinkAllColumns(true);
final String tag = "tag";
for (int i= 0; i < reportsRepository.size(); i++) {
Report tempReport = reportsRepository.get(i);
TableReportRow row = new TableReportRow(this, tempReport);
// ...
row.addView(tvName);
row.addView(tvPath);
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// This is where I need help.
}
});
table.addView(row);
}
Now I need to perform casting for the view in onClick() to get the access to the GetReport() method to get the actual corresponding report for the row, but I can't seem to get it right. Can some one help me with this one, please? Any help would be appreciated.
You can cast it to a TableReportRow. When onClick is invoked, the view the listener is attached to is passed in as the parameter.
This is useful because it allows the same listener to be recycled for multiple buttons and you can identify the action on the view(based on text, contents, id, etc...)
The View parameter in the onClick event is the View that the handler is bound to. So in your case it will be an instance of TableReportRow, hence:
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TableReportRow local = (TableReportRow) v;
}
});
Alternatively define your row as final in the outer block:
final TableReportRow row = new TableReportRow(this, tempReport);
...
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// row is in scope here
row.getVirtualChildCount();
}
});
TableReportRow row = new TableReportRow(this, tempReport);
row.setId(i);//set an id for this.
//...
row.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
TableReportRow myRow=(TableReportRow)v;
int id=myRow.getId();//your id.
myRow.getReport();//yourReport
}
}
});
I have actually read several answers to this but they are so different than the simple way I am implementing click responses that I am wondering if there is a way to add something simple to what I am doing to create an onLongClick responas.
Basically, all my XML code is written with statements like this:
android:onClick="onSync"
Then my Java has:
public void onSync(View v) {
...
Toast toast3=Toast.makeText(this, "Sync was pressed",Toast.LENGTH_SHORT);
toast3.show();
}
What I would like to do is have a different function that is called when the button gets a long press. Right now, a long press causes the same action as a short press.
Specifically, I would like to know how to interface to a routine such as this:
public void onSyncLong(View v) {
...
Toast toast3=Toast.makeText(this, "Long Sync was pressed",Toast.LENGTH_SHORT);
toast3.show();
}
I would certainly appreciate any help on this problem. It would be great if the reply told me what to do in the XML and in the Jave. Thanks so much.
----------------------------UPDATE------------------------
Here is my onCreate code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.start_meters);
textLL = (TextView)findViewById(R.id.textLL);
textTimer = (TextView)findViewById(R.id.textTimer);
textTimeToLine = (TextView)findViewById(R.id.textTimeToLine);
Button button = (Button) findViewById(R.id.button_sync);
button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
return true;
}
});
}
And here is the button XML segment
<Button
android:id="#+id/buttonSync"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Gun/Sync"
android:onClick="onSync"
android:textSize="#dimen/font_small"
android:background="#drawable/round_button"
android:padding="3sp"
android:longClickable="true"/>
------------Final Update----------------
Here is the working code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.start_meters);
textLL = (TextView)findViewById(R.id.textLL);
textTimer = (TextView)findViewById(R.id.textTimer);
textTimeToLine = (TextView)findViewById(R.id.textTimeToLine);
Button button = (Button) findViewById(R.id.buttonSync);
button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
StartLine2.startTime = pTime + 1000*60*5;
return true;
}
});
}
You can't do this via XML. Instead, use:
Button button = (Button) findViewById(R.id.<your_id>);
button.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
return true;
}
});
Make sure this code comes after setContentView() has been called.
Also, make sure that the android:longClickable property is set to true.
In your XML, the ID is set to buttonSync, while in the Java code you're using button_sync. This is the reason for your NullPointerException, as you don't have a button called button_sync.
public class GameScoreFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.v("TTT", "GameScoreFragment.OnCreateView()");
View viewScore = inflater.inflate(R.layout.gamescorelayout, container, false);
// set onLongClick listeners for both buttons
// when player long presses any of the two buttons, scores are reset
Button tempButton = (Button) viewScore.findViewById(R.id.id_button_pone_score);
tempButton.setOnLongClickListener( mLongListener );
tempButton = (Button) viewScore.findViewById(R.id.id_button_ptwo_score);
tempButton.setOnLongClickListener( mLongListener );
return viewScore;
}
// define a variable mLongListener to hold the listener code
// and then use mLongListener to set the listener
// if we don't define the variable, then we will have to write the listener code at two places (once for each button)
private View.OnLongClickListener mLongListener = new View.OnLongClickListener() {
#Override
public boolean onLongClick(View pView) {
//reset player scores
GameFragment tempGameFragment = (GameFragment) getFragmentManager().findFragmentById(R.id.id_gamefragment);
if (tempGameFragment != null)
tempGameFragment.resetPlayersScore(false);
return true;
}
};
}
I have this code:
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
button1.setBackgroundResource(R.drawable.detailpressed);
Chapter_sync.add(chapid);
}
What I am trying to do is toggle all the methods called in the following clicklistener.
Eg first time when I Click this button the setBackgroundResource(R.drawable.detailpressed) is called and on the next click same metod is called with different drawable.
Something like toggle button.
Someone good at this plz help?
you can take a variable
int i=0;
it will increase with every click.
if(i%2==0)
set one image
else
set another image
How about creating an array of the drawable's IDs and saving an index:
private final int[] myDrawables = {R.drawable.detailpressed, R.drawable.detailpressed1, ...};
//...
button1.setOnClickListener(new OnClickListener() {
int index = 0;
#Override
public void onClick(View v) {
button1.setBackgroundResource(myDrawables[index++ % myDrawables.length]);
Chapter_sync.add(chapid);
}
}
declare variable as
boolean isOddClicked = true;
And update your click listener as
button1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Do stuff here for chnaging background of button
if(isOddClicked) {
button1.setBackgroundResource(R.drawable.detailpressed);
isOddClicked = false;
} else {
button1.setBackgroundResource(R.drawable.detailpressed_SECOND_IMAGE);
isOddClicked = true;
}
//Do your task
Chapter_sync.add(chapid);
}
NOTE: If your requirement moves between two images then you can use toggle button and customize it. It will work for same as your requirement.
if xml as the following
<code>
<Button
android:id="#+id/btnListView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="#drawable/list_view"
android:onClick="switchToListView"
android:visibility="visible"
/>
<Button
android:id="#+id/btnGridView"
android:layout_width="35dp"
android:layout_height="35dp"
android:background="#drawable/grid_view"
android:onClick="switchToGridView"
android:visibility="gone"
/>
<code>
handling Code will be like
<code>
public void switchToListView(View view) {
(Button) findViewById(R.id.btnListView).setVisibility(View.GONE);
(Button) findViewById(R.id.btnGridView).setVisibility(View.VISIBLE);
}
public void switchToGridView(View view) {
(Button) findViewById(R.id.btnGridView).setVisibility(View.GONE);
(Button) findViewById(R.id.btnListView).setVisibility(View.VISIBLE);
}
</code>