Best way to set a big Amount of text to Textview - android

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.

Related

How can i rename a buttons / textviews text in a fragment?

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")

Tab Layout Select method does not call onTabSelected in android

My application is using Tab Layout . I am creating four tabs in MainActivity(This is the activity which gets launched when i open the Application).
Each tab is associated with a fragment using viewpager . Please refer the below code:
TabLayout tabLayout;
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
pagerAdapter = new MainFragmentPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
}});
This is what i am doing in the onCreate method of the MainActivity.
By default the application shows the first tab as the selected tab . But i want to show the 2ndTab as the selected tab every time application is launched fresh.
So for this i am using following code in the onResume method of MainActivity:
tabLayout.getTabAt(1).select(); //position 1 - means second tab , 0 means tab 1
This api selects the 2nd tab properly.
But Problem 1:-
it does not call the onTabSelected method which i have overridden.
Problem 2: Right After calling tab.select, when i try to get the fragment associated with the 2nd tab, it returns null.
#Override
public void onResume() {
tabLayout.getTabAt(1).select();
Fragment page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 1); // position 1 is for 2nd tab.
}
here page is coming as NULL. But if i try to get the page after 2 seconds (using Android Handler postDelayed ). It gives me the proper page value .This is how i get it using handler:
#Override
public void onResume() {
tabLayout.getTabAt(1).select();
handler.postDelayed(getFragment, 2000);
}
private Runnable getFragment = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Fragment page = null;
page = getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.viewpager + ":" + 1); // position 1 is for 2nd tab
}
};
Now the page value will come proper from the run method.
So how do i resolve problem 1 and is the using handler solution good for second problem.
Hey please check the code below:
TabLayout tabLayout;
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
pagerAdapter = new MainFragmentPagerAdapter(this,getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(1);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new
TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
}});

SlidingTabLayout and ViewPager: how to load the current fragment and not the adjacent one at the same time?

I am trying to implement a sliding tab layout that and each fragment should only load when the tab is selected instead i get the adjacent fragment loading, I have tried setOffScreenPageLimit(1) as my code shows but still the adjacent fragment gets loaded any assistance please ???
private SlidingTabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
viewPager.setOffscreenPageLimit(1);
tabLayout = (SlidingTabLayout) findViewById(R.id.tabs);
if (tabLayout != null) {
tabLayout.setViewPager(viewPager);
tabLayout.setDistributeEvenly(true);
tabLayout.setSelectedIndicatorColors(R.color.md_amber_600);
}
I can see you have used setOffScreenPageLimit as 1. It means you are loading only 1 extra screen at a time using viewPager, when actually you want to load nothing. It is not possible to set 0 value for setOffScreenPageLimit this method, actually you can set it but it will not work.
So, it is not possible to achieve this using view pager. If you still want to perform such a functionality, you can use FrameLayout and switch between the fragments based on tab selection.
Below is the tab selection code sample:
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
switchToTab(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});

Android: Updating tab content

I am new to Android development. I have a ViewPager which holds TabLayout (that has fixed number of tabs). The ViewPager has SectionPagerAdapter (that has a fragment corresponding to tabs).
Now, I want to update tab content when user selects the tab and as it becomes visible (or when user wants to refresh the content).
But I am not sure which is correct way I can do this.
So far till now I found two solutions:
1) Add listener to TabLayout:
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener()
{
#Override
public void onTabSelected(TabLayout.Tab tab)
{
mViewPager.setCurrentItem(tab.getPosition());
// Update tab containts here
}
#Override
public void onTabUnselected(TabLayout.Tab tab)
{
}
#Override
public void onTabReselected(TabLayout.Tab tab)
{
}
});
2) Use ViewPager.OnPageChangeListener to get callbacks for when a page fragment (inside Tab) becomes visible:
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener()
{
#Override
public void onPageSelected(int position)
{
// Update tab containts here
}
});
Can someone expert in this please advice me?
The way a viewpager adapter works (with tabs) is that once you add your fragments to the viewpager, then you basically need to add content to your fragments and let the adapter manage which fragment is visible when a given tab is selected.
So, by simply using : OnTabSelectedListenerinterface on your tabLayout, all you need to do is `setCurrentItem(tab.getPosition()); on your viewPager reference (from your layout).
You can have a method like this to add fragments to your viewPagerAdapter:
private void setupViewPager(ViewPager viewPager){
//then create an instance of your ViewPagerAdapter class here
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
//then add fragments for each TAB here
//by calling a method inside your Adapter like this
adapter.addFrag(new FragmentOne(), "TITLE HERE");
adapter.addFrag(new FragmentTwo(), "TITLE TWO");
//Now set your adapter here
viewPager.setAdapter(adapter);
}
Now in your fragments, you can show different content accordingly.
I hope this helps!

How to change ViewPager's page?

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);
}
}

Categories

Resources