OnClickListener inside a for loop - android

I'm getting a "Error:(99, 95) error: local variable i is accessed from within inner class; needs to be declared final" for trying to use the "i" variable from a For loop in the OnClick method.
I tried to put this "i" inside a global variable but then I get a "ArrayIndexOutOfBoundsException".
But I can't think in another way to do so.
private void createTextViews(TextView[] textViewArray, LinearLayout linearLayout){
for (int i = 0; i < keys.length; i++) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(20, 0, 0, 20);
TextView newView = new TextView(getActivity());
newView.setLayoutParams(layoutParams);
newView.setText("Watch the Trailer " + (i + 1));
newView.setTextSize(22);
newView.setTextColor(getResources().getColor(R.color.words));
newView.setBackgroundColor(getResources().getColor(R.color.button));
newView.setHighlightColor(getResources().getColor(R.color.background));
newView.setPadding(5, 5, 5, 5);
newView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(YOUTUBE_URL+keys[i]));
startActivity(intent);
}
});
linearLayout.addView(newView);
textViewArray[i] = newView;
}
}
How can I do this?
--------------
EDIT
Here's the log for the ArrayIndexOutOfBoundsExeption:
11-03 01:08:13.866 32159-32159/app.com.example.android.popularmovies E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: app.com.example.android.popularmovies, PID: 32159
java.lang.ArrayIndexOutOfBoundsException: length=3; index=3
at app.com.example.android.popularmovies.Detail_ActivityFragment$1.onClick(Detail_ActivityFragment.java:99)
at android.view.View.performClick(View.java:4456)
at android.view.View$PerformClick.run(View.java:18465)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

you must init new final int value
add final int ex = i;
before setOnClickListener
and don't forget to change
Uri.parse(YOUTUBE_URL + keys[i]));
to
Uri.parse(YOUTUBE_URL + keys[ex]));

The reason you are getting the out of bound exception is because in the last loop you are i++ing although it is not entering the loop again but the i that is a class variable is now out of bound. So the whole approach of putting i as a class variable will not work in your case.
A way to achieve this is to actually save i in a tag in the view and then read that tag from the view that is clicked.
newView.setTag(i)
Then in the onClick
v.getTag()
above can be used to get the i

Related

Set tag for newly(Runtime) created element

I'm creating radio buttons like this in a fragment programmatically in a for loop (i++)
for (int i = 1; i < priceList.length(); i++) {
JSONObject priceObj = (JSONObject) priceList.get(i);
String catName = priceObj.getString("categoryName");
String uid = i*(i+100)+20;
RadioButton rdbtn = new RadioButton(getActivity().getApplicationContext());
rdbtn.setId((row * 2) + i);
rdbtn.setText(catName);
rdbtn.setTextColor(R.color.colorPrimary);
ll.addView(rdbtn);
}
linearLayout.removeAllViews();
linearLayout.addView(ll);
i want to add that uid as tag, but if i add .setTag(uid) it is giving error like below
FATAL EXCEPTION: main
Process: com.vistaraitsolutions.hoteladmin, PID: 13629
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RadioButton.setTag(java.lang.Object)' on a null object reference
at com.vistaraitsolutions.hoteladmin.FragmentStepThreeBooking.addRadioButtons(FragmentStepThreeBooking.java:226)
at com.vistaraitsolutions.hoteladmin.FragmentStepThreeBooking$1.onResponse(FragmentStepThreeBooking.java:161)
at com.vistaraitsolutions.hoteladmin.FragmentStepThreeBooking$1.onResponse(FragmentStepThreeBooking.java:157)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:72)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6856)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
and that tadio buttons not yet added to linear layout yet, aftre loop ony im adding radio group to layout! now i need to set tags.
this is code with setTag()
for (int i = 1; i < priceList.length(); i++) {
JSONObject priceObj = (JSONObject) priceList.get(i);
String catName = priceObj.getString("categoryName");
String uid = i*(i+100)+20;
RadioButton rdbtn = new RadioButton(getActivity().getApplicationContext());
rdbtn.setId((row * 2) + i);
rdbtn.setText(catName);
//rdbtn.setTag(url); here im adding setTag
rdbtn.setTextColor(R.color.colorPrimary);
ll.addView(rdbtn);
}
linearLayout.removeAllViews();
linearLayout.addView(ll);
please help me

How to get all edittext data from listview

My listview have 19 rows and i need to get all edittext data from listview and store into arraylist.
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int itemCount = mListView.getCount();
Log.d("count", ""+itemCount);
final ArrayList<String> collection = new ArrayList<>();
for(int i=0; i<itemCount; i++){
view1 = mListView.getChildAt(i);
Log.d("Position: ", ""+view1);
EditText tt = (EditText)view1.findViewById(R.id.etqty);
value = tt.getText().toString();
collection.add(value);
}
//int position = contractstoreAdapter.getItem();
Log.d("number", String.valueOf(collection));
}
});
Here is my error.
09-07 08:09:05.526 8669-8669/com.example.chintatt.cbi E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chintatt.cbi, PID: 8669
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.example.chintatt.cbi.Fragment_orderstock$1.onClick(Fragment_orderstock.java:107)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
ListView doesn't always contain the data, cause a child view is created every time it comes into display
You must have used some adapter to store the data right? Try to get all the info from there. Not from the ListView but from the adapter in which the data contains.
Hope this will help You
If u can tell how u are storing the data in Adapter it would help me further to tell your answer precisely
for (int i = 0; i <= mListView.getLastVisiblePosition() - mListView.getFirstVisiblePosition(); i++)
I believe this should be the loop that you need to implement.
EditText tt = (EditText)view1
Use above line
EditText tt = (EditText)view1.findViewById(R.id.etqty);
Why are you calling findViewById(), whether you get edittext in your view itself

When I select radio button my app crashed

I have 3 Radio buttons each radio buttons to do some performs, Using this Radio Buttons I am filtering my Results E.g for RB1 for DATE-WISE RB2 for customernames and RB3 for Productname.
Above two radio buttons working good(RB2 and RB3), but when I choose RB3(DATE-WISE) my Application Crashed.
final RadioGroup rgroup = (RadioGroup)findViewById(R.id.radioType);
final RadioButton Ta = (RadioButton)findViewById(R.id.type_a);
final RadioButton Tb = (RadioButton)findViewById(R.id.type_b);
final RadioButton Tc = (RadioButton)findViewById(R.id.type_c);
rgroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (rgroup.getCheckedRadioButtonId() == Ta.getId()) {
cus_names = listItems.get(cus_name.getSelectedItemPosition());
btn1.setVisibility(View.VISIBLE);
btn2.setVisibility(View.VISIBLE);
created_date1.setVisibility(View.VISIBLE);
created_date2.setVisibility(View.VISIBLE);
cus_name.setVisibility(View.GONE);
po_id.setVisibility(View.GONE);
}
else if (rgroup.getCheckedRadioButtonId() == Tb.getId()) {
cus_name.setSelection(0);
cus_name.setVisibility(View.VISIBLE);
btn1.setVisibility(View.GONE);
btn2.setVisibility(View.GONE);
created_date1.setVisibility(View.GONE);
created_date2.setVisibility(View.GONE);
po_id.setVisibility(View.GONE);
}
else if (rgroup.getCheckedRadioButtonId() == Tc.getId()) {
po_id.setSelection(0);
po_id.setVisibility(View.VISIBLE);
btn1.setVisibility(View.GONE);
btn2.setVisibility(View.GONE);
created_date1.setVisibility(View.GONE);
created_date2.setVisibility(View.GONE);
cus_name.setVisibility(View.GONE);
}
}
});
My Logcat:
07-28 11:47:53.243 13244-13244/com.example.Minal E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.Minal, PID: 13244
java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1
at java.util.ArrayList.get(ArrayList.java:310)
at com.example.Minal.Purchase_Pending$1.onCheckedChanged(Purchase_Pending.java:180)
at android.widget.RadioGroup.setCheckedId(RadioGroup.java:173)
at android.widget.RadioGroup.-wrap0(RadioGroup.java)
at android.widget.RadioGroup$CheckedStateTracker.onCheckedChanged(RadioGroup.java:351)
at android.widget.CompoundButton.setChecked(CompoundButton.java:159)
at android.widget.CompoundButton.toggle(CompoundButton.java:115)
at android.widget.RadioButton.toggle(RadioButton.java:76)
at android.widget.CompoundButton.performClick(CompoundButton.java:120)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
In your case the reason is cus_name.getSelectedItemPosition() return -1 (it is not a index of your listItem) and your listItem size is 0.
So you should check both of it before get value for prevent ArrayIndexOutOfBoundsException like
if(cus_name.getSelectedItemPosition() > -1 && cus_name.getSelectedItemPosition() < listItems.size()){
cus_names = listItems.get(cus_name.getSelectedItemPosition());
}
Hope this help
You have written below line at wrong position, so whenever you will get empty list it will crash your app,
cus_names = listItems.get(cus_name.getSelectedItemPosition());
So try below code for all three condition not in onle,
if(listItmes != null & listItems.size() > 0)
cus_names = listItems.get(cus_name.getSelectedItemPosition());

Android: Is it possible to have two intents int the same activity?

The following code causes my application to stop working:
// Passing values to the results activity
Intent intent = new Intent(this, TestResults.class);
intent.putExtra("results", results);
intent.putExtra("Questions", question);
intent.putExtra("CorrectAnswer", correctAnswer);
//this.startActivity(intent);
//passing the score value to the splash activity
Intent SplashIntent = new Intent(this, SplashTest.class);
SplashIntent.putExtra("score", score);
this.startActivity(SplashIntent);
Is this becuase I have two intents in the one activity?
Log Cat Crash report:
04-15 16:33:13.894: E/AndroidRuntime(2322): FATAL EXCEPTION: main
04-15 16:33:13.894: E/AndroidRuntime(2322): Process: com.example.multapply, PID: 2322
04-15 16:33:13.894: E/AndroidRuntime(2322): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.multapply/com.example.multapply.SplashTest}: android.content.res.Resources$NotFoundException: String resource ID #0x0
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread.access$800(ActivityThread.java:135)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.os.Handler.dispatchMessage(Handler.java:102)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.os.Looper.loop(Looper.java:136)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread.main(ActivityThread.java:5017)
04-15 16:33:13.894: E/AndroidRuntime(2322): at java.lang.reflect.Method.invokeNative(Native Method)
04-15 16:33:13.894: E/AndroidRuntime(2322): at java.lang.reflect.Method.invoke(Method.java:515)
04-15 16:33:13.894: E/AndroidRuntime(2322): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-15 16:33:13.894: E/AndroidRuntime(2322): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-15 16:33:13.894: E/AndroidRuntime(2322): at dalvik.system.NativeStart.main(Native Method)
04-15 16:33:13.894: E/AndroidRuntime(2322): Caused by: android.content.res.Resources$NotFoundException: String resource ID #0x0
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.content.res.Resources.getText(Resources.java:244)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.widget.TextView.setText(TextView.java:3888)
04-15 16:33:13.894: E/AndroidRuntime(2322): at com.example.multapply.SplashTest.onCreate(SplashTest.java:32)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.Activity.performCreate(Activity.java:5231)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-15 16:33:13.894: E/AndroidRuntime(2322): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
04-15 16:33:13.894: E/AndroidRuntime(2322): ... 11 more
The crash report is from the section where the app has crashed
Edit: Class that has the two intents:
public class Test extends Activity implements View.OnClickListener{
//declare vars
TextView text;
EditText answer;
Button submit;
int random1;
int random2;
String[] question= new String[10];//change to array?
int correctAnswer[]=new int[10];//change to array?
int[] results=new int[10];
int score=0;
int questionNumber=1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
// initialising variables
initialiseVars();
//set up random
setUpRandom();
//Set text view equal to question
text.setText(question[questionNumber-1]);
//set on click listener for submit button
submit.setOnClickListener(this);
//updateQuestion?
updateQuestion();
}
public void initialiseVars() {
text = (TextView) findViewById(R.id.tvTopRandomTest);
answer = (EditText) findViewById(R.id.etEnterAnswerRandomTest);
submit = (Button) findViewById(R.id.btnSubmitRandomTest);
}
public void setUpRandom(){
//setting up randoms
Random random= new Random();
// Generating random number between 1 and 12
random1 = random.nextInt(12) + 1;
// Generating another random number between 1 and 12
random2 = random.nextInt(12) + 1;
question[questionNumber-1]= random1 + " x " + random2 + " = ";
correctAnswer[questionNumber-1]= random1*random2; //note: possibly may not be used
}
public void updateQuestion(){
//updating question after each click
setUpRandom();
text.setText(question[questionNumber-1]);
answer.setText("");
}
public void onClick(View v){
// sets text view equal to whats typed in in editText
final String entry = answer.getText().toString();
// convert from string value to int
int a = Integer.parseInt(entry); // note: maybe change name
//setting the user answer equal to the question
results[questionNumber-1]=a;
if(a==correctAnswer[questionNumber-1]){
score++;
}
if (questionNumber < 10) {
questionNumber++;//updates question
// called after an answer is given
updateQuestion();
} else {
// Passing values to the results activity
Intent intent = new Intent(this, TestResults.class);
intent.putExtra("results", results);
intent.putExtra("Questions", question);
intent.putExtra("CorrectAnswer", correctAnswer);
//this.startActivity(intent);
//passing the score value to the splash activity
Intent SplashIntent = new Intent(this, SplashTest.class);
SplashIntent.putExtra("score", score);
this.startActivity(SplashIntent);
}
}
}
The problem is that after you call startActivity() with the first intent, the code afterward is not executed. This means that whatever data you try to access in SplashTest is not actually present. A workaround to this issue would be to save the data to internal/external storage or SharedPreferences and access it from there.
Since your arrays aren't large, we can definitely use SharePreferences to store the data.
We save each piece of data in SharedPreferences as a String-String key-value pair.
To store the int arrays, we can combine all the elements into a single String and use a comma as a delimiter.
Storing the "question" String array as a String is an interesting problem, since a String can potentially contain any character. This makes it difficult to efficiently choose a delimiter. I wrote a class called EncodeDecode to convert a String array to a String(and back) here: https://gist.github.com/liangricha/10759438. Feel free to read through the code/give feedback. It should be fully functional.
My code snippets below use the functions in my EncodeDecode.
Saving Data
To store the data in SharedPreferences, you can write:
//Grab SharedPreferences of application.
SharedPreferences.Editor editor = getSharedPreferences("Data", MODE_PRIVATE).edit();
//Use StringBuilder to build data string.
StringBuilder strBuild = new StringBuilder();
//Store "results"(int array)
for(int i = 0; i < results.length; i++)
strBuild.append(str.append(correctAnswer[i]).append(","));
editor.putString("results", strBuild.toString());
strBuild.setLength(0);
//Store "question"(String array) ***REFERENCES CLASS IN GIST ABOVE***
String arrStr = EncodeDecode.encode(question)
editor.putString("questions", arrString);
//Store "correctAnswer"(int array)
for(int i = 0; i < correctAnswer.length; i++)
strBuild.append(str.append(correctAnswer[i]).append(","));
editor.putString("correctAnswer", strBuild.toString());
//Store "score"(int)
editor.putString("score", Integer.toString(score));
//Write changes to disk.
editor.commit();
Retrieving Data
First, grab a reference to the SharedPreferences:
SharedPreferences prefs = getSharedPreferences("Data", MODE_PRIVATE);
To get the "results" int array:
String[] resultsStrs = prefs.getString("results", "").split(",");
int arrLength = resultsStrs.length;
int[] results = new int[arrLength];
for(int i = 0; i < resultsStrs.length; i++)
results[i] = Integer.parseInt(resultsStrs[i]);
To get the "question" String array:
String qStr = prefs.getString("question", "");
String[] question = EncodeDecode.decode(qStr);
To get the "correctAnswer" int array:
String[] correctAnsStrs = prefs.getString("correctAnswer", "").split(",");
int arrLength = correctAnsStrs.length;
int[] correctAnswer = new int[arrLength];
for(int i = 0; i < correctAnsStrs.length; i++)
correctAnswer[i] = Integer.parseInt(correctAnsStrs[i]);
To get the "score" int:
String scoreStr = prefs.getString("score", "");
int score = Integer.parseInt(scoreStr);
Problem is not having or not more intents in the same activity: an Intent from a java viewpoint is an object so you can allocate as many intents you'd like.
But when you do startActivity() you are stopping the current activity in order to start a new one so, after that call, any subsequent code is not garantee to be executed as it is contained in an activity which is stopping.
You have to consider the startActivity() as a no return call, like a return statement, and so not put any code after that.
The error in your crash report shows you're trying to call setText(int) (when I'm assuming you're actually trying to set it to a String passed through the Intent, which is actually being parsed as an int).
In your second Activity, you should try to call
setText(String.valueOf(your_int_variable_here));
to make sure it doesn't parse it as a Resource ID (int) instead of an actual String.

Dynamic TableRow in TableLayout

Someone could tell me why my app crash?? When I add 1 tablerow everything goes right but when i try to add more than 1 table row my app crask
public void generaLayout(){
TableLayout tabla = new TableLayout(this);
for(int i = 0; i < 2; i++){
row[i] = new TableRow(this);
tabla.addView(row[i]);
for(int j = 0; j < contador2; j++){
row[i].addView(textArray[j]);
}
}
layout.addView(tabla);
}
public void generaTextView(int i, String cad){
textArray[i] = new TextView(this);
textArray[i].setText(cad);
}
Here is the logcat
6-14 04:13:33.814: E/SurfaceFlinger(36): ro.sf.lcd_density must be defined as a build property 06-14 04:13:34.714: E/AndroidRuntime(3733): FATAL EXCEPTION: main 06-14 04:13:34.714: E/AndroidRuntime(3733): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 06-14 04:13:34.714: E/AndroidRuntime(3733): at android.view.ViewGroup.addView(ViewGroup.java:3131)
Ok, based off that log.
I think it is because you are adding the same TextView to different rows causing "The specified child already has a parent". E.g You are adding textArray[0] To row's 0, and 1. Row 1 it would crash as that textview is already associated with row 0.
You currently have a one dimensional TextView Array. and you are using that same array for each row.
If you want to store them, you are going to have to use a 2D array.
E.g
textArray[i][j]
Your generate would have to change to
public void generaTextView(int i, int j, String cad){
textArray[i][j] = new TextView(this);
textArray[i][j].setText(cad);
}
You would also have to change this
row[i].addView(textArray[j]);
to
row[i].addView(textArray[i][j]);

Categories

Resources