How to count amount of views in layout - android

Is there a way for Android Studio to show how many views that are present within an XML layout? As we all know, layouts should contain <=80 views hence any more than that then this warning appears therefore it would be very helpful to be told the amount.
LayoutName.xml has more than 80 views, bad for performance
public class FragmentApple extends android.support.v4.app.Fragment {
public FragmentApple () {
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_apple,container,false);
int num = FragmentApple.getChildCount(); Log.d("Number of views in layout: ", "" + num);
return v;
}
}

Have you tried this?:
layout.getChildCount();
UPDATE
after what we discussed in the comments, this is what you should do within your code:
public class FragmentApple extends android.support.v4.app.Fragment {
public FragmentApple () {
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_apple,container,false);
return v;
}
#Override
public void onStart(){
super.onStart()
RelativeLayout (or Linear as in your xml) rl = (RelativeLayout) v.findViewbyId(R.id.your_layout_id)
int num = rl.getChildCount();
Log.d("Number of views in layout: ", "" + num);
}
}

for new comers to this question, you could use the view hierarchy from android studio's android device monitor:
open the app from your device or an emulator, and browse to the view that you want to inspect
1- from the Studio's Menu bar open
tools -> Android -> Android device monitor
2- from Android device monitor Menu bar open
window -> open perspective -> Hierarchy view
it may load for some time.
if you want to learn more: https://developer.android.com/studio/profile/hierarchy-viewer.html

Related

use page.getTag() in viewpager2 PageTransformer

I have a ViewPager2 with 3 pages and i need to transform specifically the number 2.
I am using Fragments but in the ViewPager2's PageTransformer, we override the transformPage(View page, int position) method.
So what i have tried is to to something like :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: creating the view.");
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_edit, container, false);
view.setTag(2);
//...
return view;
and in the pageTransformer :
#Override
public void transformPage(#NonNull View page, float position) {
System.out.println("transformPage " + page.getTag());
if (page.getTag() != null) {
// do something
}
}
problem is that page.getTag() is always null. I have also tried to set the tag at the root view in my Fragment's XML file and still not working.
Thanks
You can call (page.parent as RecyclerView).getChildLayoutPosition(page) to get the index of the page.

Android using Fragment without extend the class

This is a pretty straightfoward question... i would like to use very simple fragments and tell them which layout to inflate without the need to create a class for each fragment and override the method onCreateView
in simple words i would like to do:
Fragment f = new Fragment();
f.loadfromlayout(R.layout.layout);
is there any way to achieve that?
the closest i get is:
new Fragment() {
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_send_screenshot_step1, container, false);
}
}
======================UPDATE===================
Just to clarify a bit more my requirements. What i'm trying to achieve is this:
https://developer.android.com/training/animation/screen-slide
https://developer.android.com/training/animation/anim_screenslide.mp4
Use ViewPager to create a step-by-step wizard
as shown in the official android documentation my example will load a very simple layout for each "step" (every step is a fragment)... and in order to get this using the default android components i need to create a new class extending Fragment for every single step in my wizard all of them are exaclty the same thing just specifying a different layout in the onCreateView
that is very unnelegant and a lot of repetitive code in my opinion. i would like to avoid
As many people pointed in the comments this behavior was not originally desinged to happen in android.
I found a solution that will work for my case and still fine.
public class GenericFragment extends Fragment {
public static GenericFragment newInstance(#LayoutRes int layout) {
Bundle b = new Bundle();
b.putInt("layout", layout);
GenericFragment g = new GenericFragment();
g.setArguments(b);
return g;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(getArguments().getInt("layout"), container, false);
}
}
this way i need only 1 single class extending Fragment and i can have as many pages with different layouts i want in my wizards... as long as the pages dont have "specific behavior"

Blank Fragment Contains Unwanted Parameters

I've noticed every time I create a new blank fragment it gives me some parameters at the top that I find a bit distracting and always delete. I was wondering if there's any way we can set to have these parameters not to appear when a new fragment is created?
Thanks very much.
Create a class and extends it from Fragment. You will get a clean class without any parameters.
public class SampleFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.<xml layout>, container, false);
//Your code
return rootView;
}
}
It is known issue in Android Studio 3.3.1 - 3.4
It is fixed in new android studio version.

Butterknife Fragment Injecting Views Not Working?

Can anyone explain why my View element (ListView) is null with the following code:
public class NewsFragment extends Fragment {
#InjectView(R.id.news_listView) ListView lv;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.news_layout, container, false);
ButterKnife.inject(this, view);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (lv == null) {
UIHelper.showAlert("null?");
}
}
}
Am I doing something wrong or is there something wrong with the library, because I pasted the example code to my app to get it working, but it's not working here... Any help is much appreciated!
Have you setup your IDE?
IDE CONFIGURATION
Some IDEs require additional configuration in order to enable
annotation processing.
IntelliJ IDEA — If your project uses an external configuration (like a
Maven pom.xml) then annotation processing should just work. If not,
try manual configuration.
Eclipse — Set up manual configuration
Usually this means that the annotation processor didn't do its work. That might be due to misconfiguration or random problems with the IDE. In my experience, every now and then I had to clean the project and build everything again.
This work for me:
...
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, view);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...

Update the Fragment's UI dynamically after onLoadFinished from AsyncTaskLoader - Not able to obtain ViewGroup

Previously, I have a Fragment, which update its UI based on time consuming fetch data.
public class HomeMenuFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Infos arg1 = performTimeConsumingDataStructureLoading();
// Add in various UI views in v, according to information in loaded
// data structure.
View v = inflater.inflate(R.layout.home_menu, container, false);
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
return v;
}
....
}
This is really not a good design. As sometimes, performTimeConsumingDataStructureLoading might take more than 5 seconds, and I will get ANR (Application Not Responding)
By referring http://developer.android.com/reference/android/content/AsyncTaskLoader.html, I end up with better solution. The example I encounter is, it updates its UI indirectly through an ArrayAdapter.
public class HomeMenuFragment extends SherlockFragment implements LoaderManager.LoaderCallbacks<HomeMenuFragment.Infos> {
#Override
public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {
LayoutInflater inflater = this.getLayoutInflater(null);
ViewGroup container = (ViewGroup)this.getView().getParent();
// Remove previous old views, as onLoadFinished might be triggered
// by onContentChanged too.
container.removeAllViews();
View v = inflater.inflate(R.layout.home_menu, container, false);
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
container.addView(v);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
....
}
I do not have an ArrayAdapter as I'm not using ListFragment. What I want to do is adding few TextView into few LinearLayout. Then, I will add LinearLayout to the Fragment's container.
However, the following code gives me null pointer exception.
ViewGroup container = (ViewGroup)this.getView().getParent();
What I know what is the correct way to update Fragment UI dynamically, after onLoadFinished from AsyncTaskLoader?
However, most example I encounter is, they update their UI indirectly
through an ArrayAdapter.
Using a Loader doesn't require that you must use a ListView, you can update whatever view you target in your application.
What I know what is the correct way to update Fragment UI dynamically,
after onLoadFinished from AsyncTaskLoader?
Get a reference to the container from the Fragment's view where you'll place the extra views and add the new views.
#Override
public void onLoadFinished(Loader<Infos> arg0, Infos arg1) {
// for some reason the fragment's view isn't built yet so abort things
if (getView() == null) {
ViewGroup container = (ViewGroup) getView().findViewById(R.id.containerId);
ViewGroup container = getViewcontainer.removeAllViews();
// ...
// Adding several LinearLayout and TextView into v, based on
// information from loaded data structure (arg1)
// ...
container.addView(v);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_menu, container, false);;
}
For a while I was also trying to achieve the same. Based on the above answer, what worked for me was this:
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
ViewGroup container = (ViewGroup) getView().findViewById(R.id.fragment_oam);
if (container != null) {
if (adapter.getCount() == 0) {
Log.v(TAG, "Count is: " + adapter.getCount());
container.setBackgroundColor(Color.BLUE);
} else {
Log.v(TAG, "Count is: " + adapter.getCount());
container.setBackgroundColor(Color.WHITE);
}
} else {
Log.v(TAG, "Container is null");
}
}
And my Layout xml is as follows:
<?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:id="#+id/background"
android:background="#FFF">
<fragment
android:name="com.myapp.OAMCursorLoader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_oam">
</fragment>
Now when ContentResolver updates the cursor and onLoadFinished checks if the cursor is empty or has some content in it, based on this background of the visible screen, i.e. ListFragment is changed.
You can play around with background settings, use a drawable image instead of colors, it is up to you.

Categories

Resources