I have 100 buttons in layout and OnClick() method for all of it.
If I use switch I need to do case R.id.button1, ..., case R.id.button100 for all 100 buttons. How to shorten this code?
public void webClick(View v)
{
switch(v.getId())
{
case R.id.button1:
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink","file:///android_asset/chapter/chapter1.html");
startActivity(intent);
break;
case R.id.button2:
Intent intent2 = new Intent(this, Webview.class);
intent2.putExtra("weblink","file:///android_asset/chapter/chapter2.html");
startActivity(intent2);
break;
// ...
case R.id.button100:
Intent intent100 = new Intent(this, Webview.class);
intent100.putExtra("weblink","file:///android_asset/chapter/chapter100.html");
startActivity(intent100);
break;
}
}
If the URL depends directly on the ID, then try this:
public void webClick(View v)
{
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink","file:///android_asset/chapter/chapter" + v.getId() + ".html");
startActivity(intent);
}
EDITED
In the case you URL doesn't depend directly on the ID, then try mapping button IDs with URLS, like this:
Map<Integer, String> urls = new HashMap();
urls.put(R.id.button1, "file:///android_asset/chapter/chapter100.html");
// ... 1 to 100 ...
and modify the above code like this:
public void webClick(View v)
{
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink", urls.get(v.getId()));
startActivity(intent);
}
EDITED #2
If in the label of your buttons you already have the URL, a sugestion (not mine but made by #pad) would be to use it to calculate the URL this way:
public void webClick(View v)
{
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink", "file:///android_asset/chapter/chapter" + v.getText().replaceAll("Chapter ","") + ".html"); // Assuming your text is like "Chapter 50"
startActivity(intent);
}
For more number of buttons in your case, Dynamically create button in a loop and assign onclick event like..
Create one LinearLayout in your xml file.
Now add this all buttons in that LinearLayout like..
String[] urls={url1,url2.....url100}; // here write your all URLs
Button button[]= new Button[100];
LinearLayout mainlinear=(LinearLayout) findViewById(R.id.main_layer);
for (int i = 0; i < 100; i++) {
button[i] = new Button(this);
button[i].setText(i);
button[i].setTag(i+":"+URL); // URL = What you need to pass when button is click
button[i].setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
TextView selected = (TextView) v;
String tag = selected.getTag().toString();
//Here you need to write your code when button is pressed.
Intent intent = new Intent(this, Webview.class);
intent2.putExtra("weblink",urls[i]);
startActivity(intent2);
}
}
mainlinear.addView(button[i]);
You might want to use a ListView. If you want to have buttons, then use a ListView, which has one button in each item's layout.
Then, you setup a onItemClickListener. You get the position of that button (the first one has position 0, the second has position 1, etc.). Then compose a link:
String link= "file:///android_asset/chapter/chapter" + (position +1) + ".html";
The rest of your code, would be the same (intent.putExtra("weblink", link);)
My suggestion is to use a ListView or GridView for this case and save the file names in an ArrayList. Then you do something like this:
List<String> urlList = new ArrayList<String>();
urlList.add("file:///android_asset/chapter/chapter1.html");
urlList.add("file:///android_asset/chapter/chapter2.html");
// and so on
ListView listView = (ListView)findViewById(R.id.listView);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.id.simple_list_item_1, urlList);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink", urlList.get(position));
startActivity(intent);
}
});
This would be a nice implementation because you would avoid using 100 Buttons and OnClickListeners to save some ressources.
Edit: This code should be running, just put it in onCreate() for some testing. All you have to do is to define a ListView in your layout.xml insteed of the 100 buttons like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView">
</ListView>
</LinearLayout>
If you really wanna use this with Buttons than follow morgano's suggestion.
I think that this should be working:
public void webClick(View v)
{
String stringID = String.valueOf(v.getId());
String[] temp = stringID.split("utton");
stringID = "file:///android_asset/chapter/chapter" +temp[1]+ ".html"
Intent intent = new Intent(this, Webview.class);
intent.putExtra("weblink",stringID);
startActivity(intent);
}
public void webClick(View v)
{
Intent intent = new Intent(this, Webview.class);
switch(v.getId())
{
case R.id.button1:
intent.putExtra("weblink","file:///android_asset/chapter/chapter1.html");
startActivity(intent);
break;
case R.id.button2:
intent.putExtra("weblink","file:///android_asset/chapter/chapter2.html");
startActivity(intent);
break;
case R.id.button3:
intent.putExtra("weblink","file:///android_asset/chapter/chapter3.html");
startActivity(intent);
break;
.
.
.
.
case R.id.button100:
intent.putExtra("weblink","file:///android_asset/chapter/chapter100.html");
startActivity(intent);
break;
default:
break;
}
}
Related
The app has a MainActivity with 6 editText fields, and a button. There are 5 more activities, named Activity2, Activity3, etc. Now, When a user enters names in editText fields, and press a button, the app should find out how many editText fields are filled, and open the activity with a corresponding number in it's name.
Example:
If only one field is filled, a toast should appear, saying More players.
If two fields are filled, app opens Activity2.
If three fields are filled, app opens Activity3, etc.
Now, to the problem. I am missing something out, and can't find out what. Here is MainActivity.java
public class MainActivity extends AppCompatActivity {
private EditText editText1,editText2,editText3,editText4,editText5,editText6;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = findViewById(R.id.btn);
editText1 = findViewById(R.id.editText1);
editText2 = findViewById(R.id.editText2);
editText3 = findViewById(R.id.editText3);
editText4 = findViewById(R.id.editText4);
editText5 = findViewById(R.id.editText5);
editText6 = findViewById(R.id.editText6);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = MainActivity.class;
switch (filledFileds){
case 1:
Context context = getApplicationContext();
CharSequence text = "You need more players!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
break;
case 2:
newClass = Activity2.class;
System.out.println("Activity2");
break;
case 3:
newClass = Activity3.class;
System.out.println("Activity3");
break;
case 4:
newClass = Activity4.class;
System.out.println("Activity4");
break;
case 5:
newClass = Activity5.class;
System.out.println("Activity5");
break;
case 6:
newClass = Activity6.class;
System.out.println("Activity6");
break;
default:
}
Intent intent = new Intent(MainActivity.this, newClass);
}
});
}
private int countFilledFields() {
ArrayList<EditText> editTexts = new ArrayList<>();
editTexts.add(editText1);
editTexts.add(editText2);
editTexts.add(editText3);
editTexts.add(editText4);
editTexts.add(editText5);
editTexts.add(editText6);
int filledNumber = 0;
for(int i = 0;i < editTexts.size() ;i++){
if(editTexts.get(i).getText()!=null && !editTexts.get(i).getText().toString().matches("")){
filledNumber += 1;
}
}
return filledNumber;
}
}
The log shows the exact number, something is not working...
Here is your click listener, with the switch omitted for brevity:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = MainActivity.class;
switch (filledFileds){
...
}
Intent intent = new Intent(MainActivity.this, newClass);
}
The problem is at the very end: you've created an Intent object ... but you're not doing anything with it. Probably you have just forgotten a startActivity() call:
Intent intent = new Intent(MainActivity.this, newClass);
startActivity(intent);
Also, looking this over, you have a problem with the case where the user only enters one EditText. As written, you'll still try to start a new activity (you'll just start a new copy of the same MainActivity, which is probably a bad idea). A better idea would be to only start the new activity if the user fills out enough EditTexts:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int filledFileds = countFilledFields();
Log.d("filled", String.valueOf(filledFileds));
Class newClass = null;
switch (filledFileds){
...
}
if (newClass != null) {
Intent intent = new Intent(MainActivity.this, newClass);
startActivity(intent);
}
}
You're missing one thing:
startActivity(intent);
I have about 50 activities in my app and I have an algorithm which displays the title of like 10 of those activities in the form of buttons in a super activity and sets an onclicklistener to each button which contains an intent and it calls the specific activity. I tried to do this via an array of intents but I got no success. Any suggestions on how I can perform this?
package plkk.developers.com.livfit;
// this is my string which contains name of activities
final String ActivityIdMen[] = { "Deadlift", "Pushups", "Barbell_Bench", "Military_Press", "Barbell_Curl", "Close_Bench", "Seated_Cable", "Chinup", "Overhead_Press",
"Power_Clean", "Jumping_Rope", "Hiit", "Barbell_Bench", "Deadlift", "Lat_Pulldown", "Barbell_Curl", "Skull_Crusher", "Diamond_Dips", "Squats",
"Hill_Running", "Jumping_Rope", "Stationary_Bike", "Hiit", "Chinup", "Torso_Rotation", "Prone_Plank", "Medicine_Squat", "Front_Squat"
};
// this is a fragment of the algorithm where I need help
if(BMI<18.5){
for(i=0;i<=8;i++) {
Button btn = new Button(this);
LinearLayout.LayoutParams P = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
P.weight = 1;
btn.setLayoutParams(P);
btn.setText(ActivityTextMen[i]);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Class clas = null;
try{
clas = Class.forName("plkk.developers.com.livfit."+ActivityIdMen[i]);
}catch (ClassNotFoundException c){
c.printStackTrace();
}
if (clas!=null) {
Intent intent = new Intent(view.getContext(), clas);
startActivity(intent);
}
}
});
ll.addView(btn);
}
// the intent always directs me to the class at i=9 (in the above case. I tried solving it by using array of intents but couldn't do that properly.
Remove the weight assigmnent.
Did you declare your activities in te manifest file?
Updated
Try to set a Tag with the index. Then use the value of the tag of your button to get the value.
if(BMI<18.5){
for(i=0;i<=8;i++) {
Button btn = new Button(this);
LinearLayout.LayoutParams P = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
P.weight = 1;
btn.setTag(i);
btn.setLayoutParams(P);
btn.setText(ActivityTextMen[i]);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Class clas = null;
try{
clas = Class.forName("plkk.developers.com.livfit."+ActivityIdMen[Integer.parseInt(""+btn.getTag())]);
}catch (ClassNotFoundException c){
c.printStackTrace();
}
if (clas!=null) {
Intent intent = new Intent(view.getContext(), clas);
startActivity(intent);
}
}
});
ll.addView(btn);
}
I'm new to android development and I am creating an android application that works like "4 Pics 1 Word" for my project. I'm having difficulties in storing ArrayList in SharedPreferences or in the internal storage of the android phone. The reason why is because I am randomizing the next activity using random generator and ArrayList. Any suggestions or ideas that my help my case? Thank you in advance! I've been stuck here for hours now.
This is my MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btnStart;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// We are creating a list, which will store the activities that haven't been opened yet
ArrayList<Class> activityList = new ArrayList<>();
activityList.add(first.class);
activityList.add(second.class);
activityList.add(third.class);
activityList.add(fourth.class);
activityList.add(fifth.class);
Random generator = new Random();
int number = generator.nextInt(5) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
activity = first.class;
// We are adding the number of the activity to the list
activityList.remove(first.class);
break;
case 2:
activity = second.class;
activityList.remove(second.class);
break;
case 3:
activity = third.class;
activityList.remove(third.class);
break;
case 4:
activity = fourth.class;
activityList.remove(fourth.class);
break;
default:
activity = fifth.class;
activityList.remove(fifth.class);
break;
}
// We use intents to start activities
Intent intent = new Intent(getBaseContext(), activity);
// `intent.putExtra(...)` is used to pass on extra information to the next activity
intent.putExtra("ACTIVITY_LIST", activityList);
startActivity(intent);
}
}
And here's my first activity:
public class first extends AppCompatActivity implements View.OnClickListener{
EditText etAnswer;
Button btnGo;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
etAnswer = (EditText) findViewById(R.id.etAnswer);
btnGo = (Button) findViewById(R.id.btnGo);
btnGo.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnGo:
String answer = etAnswer.getText().toString();
if(answer.equals("Jose Rizal") || answer.equals("jose rizal") || answer.equals("Rizal") || answer.equals("rizal") ){
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
dlgAlert.setMessage("The famous Rizal monument in Luneta was not the work of a Filipino but a Swiss sculptor named Richard Kissling?" +
"Source: http://www.joserizal.ph/ta01.html");
dlgAlert.setTitle("Did you know that ...");
dlgAlert.setPositiveButton("Next",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ArrayList<Class> activityList = new ArrayList<>();
Bundle extras = getIntent().getExtras();
activityList = (ArrayList<Class>) extras.get("ACTIVITY_LIST");
if(activityList.size() == 0) {
Context context = getApplicationContext();
CharSequence last = "Congratulations! You just finished the game! Please wait for the next update!";
int durationFinal = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, last, durationFinal);
toast.show();
} else {
// Now, the random number is generated between 1 and however many
// activities we have remaining
Random generator = new Random();
int number = generator.nextInt(activityList.size()) + 1;
Class activity = null;
// Here, we are checking to see what the output of the random was
switch(number) {
case 1:
// We will open the first remaining activity of the list
activity = activityList.get(0);
// We will now remove that activity from the list
activityList.remove(0);
break;
case 2:
// We will open the second remaining activity of the list
activity = activityList.get(1);
activityList.remove(1);
break;
case 3:
// We will open the third remaining activity of the list
activity = activityList.get(2);
activityList.remove(2);
break;
case 4:
// We will open the fourth remaining activity of the list
activity = activityList.get(3);
activityList.remove(3);
break;
default:
// We will open the fifth remaining activity of the list
activity = activityList.get(4);
activityList.remove(4);
break;
}
// Note: in the above, we might not have 3 remaining activities, for example,
// but it doesn't matter because that case wouldn't be called anyway,
// as we have already decided that the number would be between 1 and the number of
// activities left.
// Starting the activity, and passing on the remaining number of activities
// to the next one that is opened
Intent intent = new Intent(getBaseContext(), activity);
intent.putExtra("ACTIVITY_LIST", activityList);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
dlgAlert.setCancelable(true);
dlgAlert.create().show();
}else{
Context context = getApplicationContext();
CharSequence text = "Wrong! Try Again.";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
break;
}
}
}
Okay, this is a horrible hack and I don't endorse it in any way, but since you are so close to finishing your app, I propose a workaround:
Instead of storing an ArrayList<Class> in your SharedPreferences (which is impossible), store a HashSet<String> containing the fully qualified names of your classes via putStringSet().
In order to get the String representations of the fully qualified names of your classes you need to call getName(), e.g. first.class.getName().
Then, you can get your Set<String> from SharedPreferences using getStringSet() and create a Class instance for each String in that set via Class.forName().
I m working on a project i have two categories Cricketers and Animals on one activity as Button and a Text View on other activity i want to change the text of Text View when ever i presses the Button i.e If Cricketer then set text to cricketer same goes for animal.
OnClick Listner for both buttons: On Activity 1
public void onClickcricketer(View view){
Intent i = new Intent(this,offlineQuestionsession.class);
final Button b = (Button)findViewById(R.id.btncricket);
String crickettext = b.getText().toString();
i.putExtra("Cricket",crickettext);
startActivity(i);
}
public void onClickanimal(View view){
Intent i = new Intent(this,offlineQuestionsession.class);
final Button b = (Button)findViewById(R.id.btnanimal);
String animaltext = b.getText().toString();
i.putExtra("Animal",animaltext);
startActivity(i);
}
Code on Activity 2:
Bundle cricketData = getIntent().getExtras();
if (cricketData == null){
return;
}
String Cricket = cricketData.getString("Cricket");
final TextView c = (TextView)findViewById(R.id.txtCategryShow);
c.setText(Cricket);
Bundle AnimalData = getIntent().getExtras();
if (AnimalData == null){
return;
}
String Animal = AnimalData.getString("Animal");
final TextView a = (TextView)findViewById(R.id.txtCategryShow);
a.setText(Animal);
This method just show animal text in Text view.. when i click Crcketer button it shows nothing
First perform an onClick method:
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String toExtra = "" + btn.getText();
Intent i = new Intent(this,NextActivity.class);
i.putExtra("key",toExtra);
}
});
then in the new Activity OnCreate method add:
Intent i = getIntent();
String fromExtra = intent.getStringExtra("key");
and finally setText to your TextView:
txt.setText(fromExtra)
It is doing correct, see your code again, On same TextView you are setting text Animal which is null in case of clicking cricket ..
Try this in second activity:
String Cricket = getIntent().getStringExtra("KEY");
final TextView c = (TextView)findViewById(R.id.txtCategryShow);
c.setText(Cricket);
And make your methods like this:
public void onClickcricketer(View view){
Intent i = new Intent(this,YourNewActivity.class);
final Button b = (Button)findViewById(R.id.txv_cricket);
String crickettext = b.getText().toString();
i.putExtra("KEY",crickettext);
startActivity(i);
}
public void onClickanimal(View view){
Intent i = new Intent(this,YourNewActivity.class);
final Button b = (Button)findViewById(R.id.txv_animal);
String animaltext = b.getText().toString();
i.putExtra("KEY", animaltext);
startActivity(i);
}
I've developed a simple tabwidget with the help of a tutorial. It looks like this:
My goal is: When a user clicks is in the "day Tab" and clicks "Today tab" the today tab must pass the control of today activity back to day activity to show the current day day.
eg. If I am in day tab and I click today tab. The function of the TODAY tab is to show the current date in the day tab. This applies to both Month and Week tab. Which means if a user has month tab active and then clicks today tab: the today tab must show the current month in the same activity.
Data flow: month activity -> today activity -> month activity
How can I achieve this task ?
I've tried to put in simple words, if you didn't understand please tell me. I will rephrase the question.
Here is the code I used to setup my Tabs
public class Secondactivity extends TabActivity {
private TabHost mTabHost;
private void setupTabHost() {
mTabHost = getTabHost();
}
setupTabHost();
mTabHost.getTabWidget().setDividerDrawable(se.copernicus.activity.R.drawable.tab_divider);
setupTab(new TextView(this), getString(R.string.month));
setupTab(new TextView(this), getString(R.string.week));
setupTab(new TextView(this), getString(R.string.day));
setupTab(new TextView(this), getString(R.string.today));
mTabHost.setCurrentTabByTag(getString(R.string.month));
private void setupTab(final View view, final String tag)
{
View tabview = createTabView(mTabHost.getContext(), tag);
if (tag.compareTo(getString(R.string.month)) == 0)
{
Intent intent = new Intent(getApplicationContext(), MonthActivity.class);
TabSpec setContent = mTabHost.newTabSpec(getString(R.string.month)).setIndicator(tabview).setContent(new TabHost.TabContentFactory()
{
public View createTabContent(String tag)
{
return view;
}
});
setContent.setContent(intent);
mTabHost.addTab(setContent);
}
if (tag.compareTo(getString(R.string.week)) == 0)
{
Intent intent = new Intent(getApplicationContext(), WeekActivity.class);
TabSpec setContent = mTabHost.newTabSpec(getString(R.string.week)).setIndicator(tabview).setContent(new TabHost.TabContentFactory()
{
public View createTabContent(String tag)
{
return view;
}
});
setContent.setContent(intent);
mTabHost.addTab(setContent);
}
if (tag.compareTo(getString(R.string.day)) == 0)
{
Intent intent = new Intent(getApplicationContext(), DayActivity.class);
TabSpec setContent = mTabHost.newTabSpec(getString(R.string.day)).setIndicator(tabview).setContent(new TabHost.TabContentFactory()
{
public View createTabContent(String tag)
{
return view;
}
});
setContent.setContent(intent);
mTabHost.addTab(setContent);
}
if (tag.compareTo(getString(R.string.today)) == 0)
{
Intent intent = new Intent(getApplicationContext(), DayActivity.class);
TabSpec setContent = mTabHost.newTabSpec(getString(R.string.today)).setIndicator(tabview).setContent(new TabHost.TabContentFactory()
{
public View createTabContent(String tag)
{
return view;
}
});
setContent.setContent(intent);
mTabHost.addTab(setContent);
}
}
private static View createTabView(final Context context, final String text)
{
View view = LayoutInflater.from(context).inflate(R.layout.tabs_bg, null);
TextView tv = (TextView) view.findViewById(R.id.tabsText);
tv.setText(text);
return view;
}
override onTabChange() , which will tell you about cureent tab no. and next tab no.
if(nextTab == DayTab)
compare currentTab and acordingly pass a flag to day Tab .
i am not sure whenther you can bind detail with intent , if so use application level data sharing like Application class implementation or singlton object .
Try overriding onTabChanged() and passing your intent or setting your flag there. This may help:
#Override
public void onTabChanged(String tabId) {
switch (tabId)) {
case 0:
// Tab 1
break;
case 1:
// Tab 2
break;
case 2:
// Tab 3
break;
case 3:
// Tab 4
break;
}
}