I want to rename different things (Buttons and Textviews) in a app from the code.
But because those are in a fragment for a Tabview this wont work and will lead to a crash:
someTextview.setText("some Text");
I have tried this Stack Overflow solution and this one, but both solutions didnt work.
Is there something else that i could try?
In your onCreateView() function first inflate the view like this
View view = inflater.inflate(R.layout.xyz, container, false);
then
TextView txtview = (TextView) findViewById(R.id.ANINRHinten);
txtview.setText("Something");
It will solve your problem.
I tried to put the .setText inside the onCreate main function, as well as the functions in the fragment class.
I didn't get any errors at all. If the setText is in the main onCreate function it compiles and opens on the simulator but crashes before doing anything.
When i tried to use it in the fragment function onCreateView, the app functions without any crashes or errors, but also the setText had no effect.
I have done the whole thing like you said from the start:
TextView txtview;
//Inside void onCreate:
txtview = (TextView) findViewById(R.id.ANINRHinten);
txtview.setText("Something");
Did you define your textView?
If you didn't you can define it like below :
TextView textView = (TextView) findViewById(R.id.text_view_id);
textView.setText("")
or if you use binding define it and use it like :
binding.textView.setText("")
I started programing with Java and Android Studio a week ago, so feel free to tell me what else i can improve.
private TextView waitForConn;
private TabLayout maintab;
private ViewPager page;
private TabItem tablicht, tabadmin;
public PagerAdapter pagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*For future implementations of BLE
setContentView(R.layout.activity_main);
waitForConn = (TextView) findViewById(R.id.wait_for_connection);
waitForConn.setText("Suche Schnapsiinator...");
waitForConn.setTextColor(Color.GREEN);
waitForConn.setText("Verbinden...");
waitForConn.setText("Verbunden");
*/
setContentView(R.layout.main_menu);
maintab = (TabLayout) findViewById(R.id.tabLayout);
tablicht = (TabItem) findViewById(R.id.licht_tab);
tabadmin = (TabItem) findViewById(R.id.admin_tab);
page = findViewById(R.id.viewpager_lichtadmin);
pagerAdapter = new PageAdapter(getSupportFragmentManager(), maintab.getTabCount());
page.setAdapter(pagerAdapter);
//Compiler says "error: incompatible types: int cannot be converted to byte[]"
View view = Inflater.inflate(R.layout.main_menu, page, false);
//at: ^
maintab.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
page.setCurrentItem(tab.getPosition());
if(tab.getPosition() == 0){
pagerAdapter.notifyDataSetChanged();
}else{
pagerAdapter.notifyDataSetChanged();
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
page.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(maintab));
}
In what function is that code? What error have you get?
have you take the id of that textview? we need more information.
Btw, if you create a variable like this on your onCreateView
button = findViewById(R.id.idOfTheButton)
then you can use it on youre OnViewCreated like you wrote in the question.
button.setText("text")
Related
I faced a new problem.
In my app, there is a part we called it X.
The X part have 5 tab ( using Viewpager and ...)
When user click on a button to start X activity, because, I must set text for all of the tabs (and there is 5 of them),there is a delay, based on the phone it's different, on low level phone its about, 4-7 second!!!
so, what can i do to solve the problem?
my way:
1- change my UI design and split the 5 tab into, 5 single activity.
2- use an progress bar( or something like progress bar) and don't change my design.( the problem is i don't know how to do this, i mean i don't know when all of the text are set)
what is the other solutions?
So, if i want to use AsynckTask, the code would be like this right?
Main:
public class Law_main extends AppCompatActivity {
FrameLayout fl_TEMP;
TextView btn_ASD;
ViewPager viewPager;
PagerAdapter adapter;
TabLayout tabLayout;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.law_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("TAB 1"));
tabLayout.addTab(tabLayout.newTab().setText("TAB 2"));
tabLayout.addTab(tabLayout.newTab().setText("TAB 3"));
tabLayout.addTab(tabLayout.newTab().setText("TAB 4"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
fl_TEMP = (FrameLayout) findViewById(R.id.TEMP);
btn_ASD = (TextView) findViewById(R.id.ASD);
new TxtTimer().execute();
final View appbar = findViewById(R.id.appbar);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private class TxtTimer extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1, true);
progressBar.setVisibility(View.GONE);
}
}
}
this code act like this:
When user Click on to open X activity, user stay in the activity and then after a while, when all text got set, the x activity is open, so it's not helping at all.
Were am i wrong?
Depending on how you are retrieving your text, consider using an AsyncTask. You can also put a progress circle on the fragment whilst it is loading so that the app doesn't appear to have frozen.
Building on what RobVoisey stated, and not knowing exactly your use case, I would load the first tab's text first to give the user something to look at and simultaneously load the text for the other tabs using AsyncTask whileshowing a loading graphic where appropriate and/or necessary.
use fragments inside your tabs and load the content on demend using fragment lifecycle, youll have a starting point of 1/5 text being loaded on each fragment.
I've studied all the fragment getArgument null pointer questions already answered and I can't seem to find a solution that works for me. My fragment is functioning properly (buttons doing proper function) except that it does not get any arguments passed in. I have set up my constructor and my calls to it various ways, and cannot avoid the NullPoint. I think it must be something around the lifecycle of the fragment, and the fragment appearing onscreen somehow not being the initiated one, but I can't get to the bottom of it. Any help will be greatly appreciated!
Fragment code:
public class BottomBar extends Fragment {
ImageButton goHome, goPending, goActive, goHelp, goChallenge;
BottomListener activityCallback;
int chalType;
String title;
String text;
//constructor log.d prints out that it has been reached
public static BottomBar init(int chalType, String ttl, String txt){
BottomBar bot = new BottomBar();
Bundle args = new Bundle();
args.putInt("chalType", chalType);
args.putString("title", ttl);
args.putString("text", txt);
bot.setArguments(args);
Log.d("Bottom Bar Init", "called");
return bot;
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
try{
activityCallback = (BottomListener) activity;
} catch (ClassCastException e){
Log.d("bottom bar onAttach","class cast");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bottombarfrag, container, false);
goHome = (ImageButton) view.findViewById(R.id.goHome);
goPending = (ImageButton) view.findViewById(R.id.goPending);
goChallenge = (ImageButton) view.findViewById(R.id.challenge);
goActive = (ImageButton) view.findViewById(R.id.goActive);
goHelp = (ImageButton) view.findViewById(R.id.getInfo);
Bundle argsin = getArguments();
//never enters this loop... argsin always null
if(argsin!=null){
Log.d("bottombar oncreate", "argsin found");
chalType = argsin.getInt("chalType", 0);
title = argsin.getString("title");
text = argsin.getString("text");
}
//.... button activities, functioning properly ....
return view;
}
and main activity code that calls it:
public class MainActivity extends FragmentActivity {
Button btn, paydemo;
TextView tv1, tv2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String ttl = "Trial1 Home";
String txt = "string1text";
BottomBar bot = BottomBar.init(0, ttl, txt);
getSupportFragmentManager().beginTransaction().add(android.R.id.content, bot).commit();
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.clickbtn);
paydemo = (Button) findViewById(R.id.PayPalDemo);
tv1 = (TextView) findViewById(R.id.textView1);
tv2 = (TextView) findViewById(R.id.textView3);
tv1.setText("try1");
tv2.setText("");
// ...other button actions
}
Follow up:
I've found that I can get the fragment that I want, however it appears as a second instance on the fragment (located on top of display, not where desired), and the original instance is there, but not functioning properly (still with no args). I think that when I initialize the fragment in my activity I am not overwriting the existing fragment that is added by the xml. Maybe I need to initialize the Support Fragment Manager and link it to the proper instance to replace it? Thoughts?
xml where originally intended fragment is located (this is the fragment I want, but not the fragment that is being communicated with).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Second Layout"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/retBut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Return" />
<fragment
android:id="#+id/bottombar"
android:name="com.example.trial1.BottomBar"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginTop="0dp"
/>
</LinearLayout>
This one is tricky. Take a look at your activity: you are setting fragment and after that calling setContentView. setContentView removes all views from android.R.id.content, i think this breaks fragment's lifecycle somehow. Moreover it looks like a concept mistake: setting fragment and wiping it out after that. I suggest making a fragment container inside R.layout.activity_main, set activity content and after that put you fragment in this container.
So I came up with a functioning answer. I'm not convinced it's the proper way to do it, but it is working.
I created an inherited class for all the classes that reference this fragment, and created a set of public variables to represents the arguments passed to the fragment. I then had each class write the public variables in the super class instead of initiating a new fragment. The fragment then referenced the same public variables to pull information from.
Again, don't think it is the proper way to do it - the argument passing exists to be efficient - but it is working for me now. If anyone has a better idea for how I could accomplish this I'm all ears.
Thanks for all the help
I am learning to develop apps for android from a book and after following the instructions I end up with the following.
private void setStartUpScreenText(){
TextView planetNameValue = (TextView)findViewById(R.id.dataView1);
planetNameValue.setText(earth.planetName);
I get wavy red underline under the dataView1 in findViewById(). Eclipse informs that dataView1 cannot be resolved or is not a field.
The complete code look like this and i get wavy red underline under all dataView. It says nothing about this error in the book.
private void setStartUpScreenText(){
TextView planetNameValue = (TextView)findViewById(R.id.dataView1);
planetNameValue.setText(earth.planetName);
TextView planetMassValue = (TextView)findViewById(R.id.dataView2);
planetMassValue.setText(String.valueOf(earth.planetMass));
TextView planetGravityValue = (TextView)findViewById(R.id.dataView3);
planetGravityValue.setText(String.valueOf(earth.planetGravity));
TextView planetColoniesValue = (TextView)findViewById(R.id.dataView4);
planetColoniesValue.setText(String.valueOf(earth.planetColonies));
TextView planetPopulationValue = (TextView)findViewById(R.id.dataView5);
planetPopulationValue.setText(String.valueOf(earth.planetPopulation));
TextView planetMilitaryValue = (TextView)findViewById(R.id.dataView6);
planetMilitaryValue.setText(String.valueOf(earth.planetMilitary));
TextView planetBasesValue = (TextView)findViewById(R.id.dataView7);
planetBasesValue.setText(String.valueOf(earth.planetBases));
TextView planetForceFieldValue = (TextView)findViewById(R.id.dataView8);
planetForceFieldValue.setText(String.valueOf(earth.planetProtection));
Here the MainActivity
public class MainActivity extends ActionBarActivity {
WorldGen earth = new WorldGen("Earth", 5973, 9.78);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
setStartUpWorldValue();
setStartUpScreenText();
}
protected void setStartUpWorldValue(){
earth.setPlanetColonies(1);
earth.setPlanetMilitary(1);
earth.setColonyImmigration(1000);
earth.setBaseProtection(100);
earth.turnForceFieldOn();
}
private void setStartUpScreenText(){
TextView planetNameValue = (TextView)findViewById(R.id.dataView1);
planetNameValue.setText(earth.planetName);
TextView planetMassValue = (TextView)findViewById(R.id.dataView2);
planetMassValue.setText(String.valueOf(earth.planetMass));
TextView planetGravityValue = (TextView)findViewById(R.id.dataView3);
planetGravityValue.setText(String.valueOf(earth.planetGravity));
TextView planetColoniesValue = (TextView)findViewById(R.id.dataView4);
planetColoniesValue.setText(String.valueOf(earth.planetColonies));
TextView planetPopulationValue = (TextView)findViewById(R.id.dataView5);
planetPopulationValue.setText(String.valueOf(earth.planetPopulation));
TextView planetMilitaryValue = (TextView)findViewById(R.id.dataView6);
planetMilitaryValue.setText(String.valueOf(earth.planetMilitary));
TextView planetBasesValue = (TextView)findViewById(R.id.dataView7);
planetBasesValue.setText(String.valueOf(earth.planetBases));
TextView planetForceFieldValue = (TextView)findViewById(R.id.dataView8);
planetForceFieldValue.setText(String.valueOf(earth.planetProtection));
}
It seems you built your views inside fragment_main.xml and not activity_main.xml.
When you first create a new android project, you have these files which are automatically created and opened:
Then, when you begin, you add views (e.g: a TextView) inside fragment_main.xml file. Finally, you tried to do a basically event with this view inside your Activity, something like this:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Using layout activity_main.xml
// You try to set a simple text on the view (TextView) previously added
TextView text = (TextView) findViewById(R.id.textView1);
text.setText("Simple Text"); // And you get an error here!
/*
* You do an fragment transaction to add PlaceholderFragment Fragment
* on screen - this below snippnet is automatically created.
*/
if(savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
You cannot run your app or sometimes you have only a white screen, because the views that you tried to call/display are into the wrong layout..
Solution: Move all your stuff inside onCreateView method into the Fragment class.
Call views and do something in the related fragment and not the parent activity.
Or you can do all inside the activity, by removing these lines which to not add a fragment on your UI:
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
This above create and add a fragment "above" your activity layout. And then, setting the right layout here:
setContentView(R.layout.fragment_main);
I am trying to make an activity have swipable tabs, with each tab having a different fragment (I dont know yet how many fragments I am going to have, so assume they will be at least 5).
So I am having problems make the parent activity with the tabs (if I said that correctly) and then the fragments themselves have some dynamically added views (text views and one image view) which get their stuff from different async tasks, executed when the fragment is showed.
Don't know if I explained it correctly, but here is my code and I'll ask you please to add in it the needed stuff.
So here is the parrent activity which must host the tabs and the fragments:
public class SecondActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
and here is one of the fragments (the others are similar):
public class Fragment1 extends Fragment {
LinearLayout layout;
ImageView iv;
String anotherURL;
ArrayList<InfoStuff> ci;
public Fragment1() {
// Empty constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
layout = (LinearLayout) rootView.findViewById(R.id.layout);
iv = (ImageView) rootView.findViewById(R.id.ivPortrait);
Bundle b = this.getArguments();
ci = b.getParcelableArrayList("infoStuff");
regionUrl = b.getString("someURL");
createViews();
return rootView;
}
public void createViews() {
TextView tv;
tv = new TextView(v.getContext());
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tv.setText("le text");
layout.addView(tv);
tv = new TextView(v.getContext());
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
tv.setText("some text");
layout.addView(tv);
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(v.getApplicationContext()).build();
ImageLoader.getInstance().init(config);
String imgUrl = "someURL";
ImageLoader.getInstance().displayImage(imgUrl, iv);
}
}
I am also having troubles making the ImageView work, as it is from an additional library (forgot the name, heres the import though import com.nostra13.universalimageloader.core.ImageLoader;)
EDIT: Sorry, forgot to mention the tabs must be swipeable
The article Creating Navigation tabs using TabHost and Fragments in Android may help you.
In this article, we will develop an Android application containing navigation tabs. There are many ways by which we can add navigation tabs to an application.
Beginning with Android 3.0, the standard way to create navigation tab is using action bar. [...]
For Android 2.x and above, we can use Action bar Sherlock library to create navigation library. [...]
In this application, we are creating navigation tabs using TabHost and Fragments. [...]
This application is developed in Eclipse 3.7.2 with ADT plugin (20.0.2) and Android SDK ( R20.0.1 ) .
I just started doing something very similar to what you want to do. I followed this tutorial on Android Hive, which was very helpful in getting the tabs, swiping, and fragments down. (The fragments in this example are just textviews with different colors, but you can easily figure out where to add in your own views).
Hope this helps - it did for me!
I'm using ViewPager in my app and define it in the main Activity. Inside onCreate method I load some number of pages from SharedPreferences and then pass it to PagerAdapter:
#Override
public int getCount() {
return numberOfPages;
}
The problem is that if I would change this number in Preferences (or another Activity) to some other less then page index I viewed before, my app crashes because this index is out of bounds when I return to the activity with this ViewPager. It can be fixed simply by changing active ViewPager's page. Is there any way to do it?
I'm not sure that I fully understand the question, but from the title of your question, I'm guessing that what you're looking for is pager.setCurrentItem( num ). That allows you to programatically switch to another page within the ViewPager.
I'd need to see a stack trace from logcat to be more specific if this is not the problem.
slide to right
viewPager.arrowScroll(View.FOCUS_RIGHT);
slide to left
viewPager.arrowScroll(View.FOCUS_LEFT);
Without checking your code, I think what you are describing is that your pages are out of sync and you have stale data.
You say you are changing the number of pages, then crashing because you are accessing the old set of pages. This sounds to me like you are not calling pageAdapter.notifyDataSetChanged() after changing your data.
When your viewPager is showing page 3 of a set of 10 pages, and you change to a set with only 5, then call notifyDataSetChanged(), what you'll find is you are now viewing page 3 of the new set. If you were previously viewing page 8 of the old set, after putting in the new set and calling notifyDataSetChanged() you will find you are now viewing the last page of the new set without crashing.
If you simply change your current page, you may just be masking the problem.
for switch to another page, try with this code:
viewPager.postDelayed(new Runnable()
{
#Override
public void run()
{
viewPager.setCurrentItem(num, true);
}
}, 100);
Supplemental answer
I was originally having trouble getting a reference to the ViewPager from other class methods because the addOnTabSelectedListener made an anonymous inner class, which in turn required the ViewPager variable to be declared final. The solution was to use a class member variable and not use the anonymous inner class.
public class MainActivity extends AppCompatActivity {
TabLayout tabLayout;
ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
// don't use an anonymous inner class here
tabLayout.addOnTabSelectedListener(tabListener);
}
TabLayout.OnTabSelectedListener tabListener = new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
// The view pager can now be accessed here, too.
public void someMethod() {
viewPager.setCurrentItem(0);
}
}