I currently have some swipe pages and in all of them I want to have list with different data.
I am still pretty new to android so I tried all possible options I could come up with:
First I tried adding some xml layouts to the insides of the page.
Second I tried creating and populating lists pragmatically.
None of the above worked out for me.
For starters I want to check if I understand the concept:
Swipe layout contains pages and data could be passed to them by getItem() Fragment type content.
And now how to achieve what I want:
I have to add LinearLayout add a child ListView and finally add a child for that the TextView element to main page template in my layout/main.xml and create a data population method.
Is there something wrong in my reasoning and that is why I can't find answer or I just have not found the right source?
CODE EXAMPLES:
main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<!--
This title strip will display the currently visible page title, as well as the page
titles for adjacent pages.
-->
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#33b5e5"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
list_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
MainActivity.java
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the adapter that will return a fragment for each of the three primary sections
// of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
...
You can do this by declaring an xml say listview.xml in which define your ListView.
You can either create a new TextView pro grammatically or create the new layout say titleview.xml in which write your title view using TextView.
Pro grammatically you can inflate both the views and pass your main layout parent view as parent to these child views.
LayoutInflater inflater = getLayoutInflater();
ListView listview = inflater.inflate(R.layout.list_view, parent);
TextView textview = inflater.inflate(R.layout.textview, parent);
layout.addView(textview);
layout.addView(listview);
Related
In my Player activity I am trying to add a view from a different XML by calling addView:
view = (ViewGroup)findViewById(R.id.player_ConstraintLayout);
notifierView = LayoutInflater.from(view.getRootView().getContext())
.inflate(R.layout.notifier, null);
view.addView(notifierView);
// view.invalidate();
The Player activity comes with this associated XML file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/player_ConstraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.android.Player">
...
</android.support.constraint.ConstraintLayout>
And the one I want to add is notifier.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
android:translationZ="9dp"
android:elevation="9dp">
</android.support.constraint.ConstraintLayout>
I have debugged the app and by inspecting variable view I can confirm that the notifierView has been added and is in the children list of the view. However the notifierView is not shown, even I have expected it to be of full screen size and red. When I inspected notifierView in debugger, it showed its mTop, mBottom, mLeft, and mRight variables being all 0. I assuming it means that the
android:layout_width="match_parent"
android:layout_height="match_parent"
have been ignored? Or is there some other reason why I don't see this notifierView at all?
EDIT/UPDATE:
Let me show you more of the code, as the previous above is a little simplified one.
In Player activity I have:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
notifier = new Notifier((ViewGroup)findViewById(R.id.player_ConstraintLayout));
...
}
and in Notifier.java I have
Notifier(ViewGroup view) {
handler = new android.os.Handler();
LayoutInflater inflater = LayoutInflater.from(view.getRootView().getContext());
notifierView = inflater.inflate(R.layout.notifier, view, false);
}
ConstraintLayout doesn't actually support match_parent for its children. You have to use this for "match parent" width:
android:layout_width="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
And this for "match parent" height:
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
Additionally, your LayoutInflater.inflate() call should be changed. When you pass null as the second argument, you don't give the system enough information to understand how to parse layout_ attributes on the inflated view; you should pass a real parent (in this case, view). However, if you change null to view, the return value of the inflate() call will change, so you have to add an additional param (attachToRoot) to make sure the rest of the semantics don't change.
LayoutInflater inflater = LayoutInflater.from(view.getRootView().getContext());
notifierView = inflater.inflate(R.layout.notifier, view, false);
(Posted solution on behalf of the question author).
Invalidate Caches / Restart helped. Android Studio sometime gets things wrong.
i work on android-studio project, and my question is about if
there is some way i can define in xml type of some item that contain
few edit text and buttons, and open listview that contain the item i create?
somthing like :
<item
<Editext(some setting)/>
<Edittext 1(some setting)/>
<Button(some setting)/>
/>
and then some adapter that adjust or something like that, that i can add to ListView.
i saw in youtube some videos that try to explain that but i get stock.. i dno't really get this.
This took my a while to figure out, but it works.
Create your Layout file just however you want. Save it as res/layout/something.txt. Example:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:text="hello"
android:layout_height="wrap_content"
android:layout_width="150dp"
android:id="#+id/text1"/>
<TextView
android:text="world"
android:layout_height="wrap_content"
android:layout_width="150dp"
android:id="#+id/text2"/>
</LinearLayout>
Use it in your code as follows:
LinearLayout mainLinearLayout = new LinearLayout(getApplicationContext());
// inflate your container
View view = inflater.inflate(R.layout.something, null);
// you can make changes to the elements like this:
TextView txt1 = (TextView) view.findViewById(R.id.text1);
TextView txt2 = (TextView) view.findViewById(R.id.text2);
view.setTag(tag);
// add to main layout
mainLinearLayout.addView(view);
Where tag is an unique integer to identify the View. You don't need to set the tag if you're using the container only once.
I didn't use an Adapter when I made this. I just used a ScrollView to make a continous list of entries. Change this to your needs.
In AndroidStudio, I selected "New->Fragment->Fragment (List)" to create a list of items. It works fine and displays all the items; however, I would like to have a title at the top.
If I add another TextView to the "fragment_item_list.xml" file, then the title appears in all the items in the list. From other questions I figured that if I create another LinearLayout xml layout file (something like "list_header.xml") and put a TextView in it, I can use a layout inflater to inflate this layout in the fragment activity, e.g. in onCreateView,
View header = inflater.inflate(R.layout.list_header,container,false);
but then I don't know what to do with header to make it display somewhere in the fragment. I can add it to the original activity by calling container.addView(header); but how can I add it to the fragment?
I don't want to change the ActionBar title, firstly just for aesthetics, and secondly because the fragment covers it up. Ideally there would be a header like in an alert dialog.
Let me try to understand you. You want to add a title to your fragment list (like an header), not in the ActionBar. Right?
Looking the fragment_item_list.xml we have this: (I follow your steps: "New->Fragment->Fragment (List)")
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:listitem="#layout/fragment_item" />
The RecyclerView is a container used for populate a list, in other words, the RecyclerView (or ListView) contain all the list only. So, you have to add another container (like LinearLayout, RelativeLayout, etc.) as root of the layout to add more views to the layout. Example using the LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World! I'm a header!"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:name="com.veroapps.myapplication.ItemFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:listitem="#layout/fragment_item" />
</LinearLayout>
With this you will have a list with a title at the top. Now, you can manage the title TextView in the ItemFragment(name of the fragment generated by Android Studio). And of course there are more ways to do that, but this is an easy one.
Hope this help you.
In your Fragment java class, there should be a method called onCreateView this is where you set the layout for your Fragment (and where the list is added). It will look something like this:
public static class ExampleFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment, container, false);
}
}
In this Fragment the layout is inflated by this code inflater.inflate(R.layout.example_fragment, container, false); and this means there's is an xml file defining the layout called example_fragment.xml.
Your code will be the same, when you find this XML file. You can add other views inside it.
You will want to add another TextView above the RecyclerView or ListView already in that file.
Something like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
...
android:text="YOUR TITLE" />
<RecyclerView
... />
</LinearLayout>
I'm following the android training in android's website. I am stuck at some point in fragments. The problem is that I can't get the reference to my textview in a fragment.
TextView view = (TextView) getActivity().findViewById(R.id.article_s);
I have two fragments in one activity. One is a plain simple ListFragment and the other is a plain simple TextView. Here is fragments and activity layout xml files.
ArticleFragment:
<!-- This is fragment_article.xml -->
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text"
android:textSize="18sp"
android:id="#+id/article_s"/>
MainActivity (My container to all fragments)
<!-- This is activity_main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_height="match_parent"
android:name="com.example.bora.fragmentsmyway.HeadlinesFragment"
android:id="#+id/headlines_fragment"
android:layout_weight="1"
android:layout_width="0dp" />
<fragment
android:layout_height="match_parent"
android:name="com.example.bora.fragmentsmyway.ArticleFragment"
android:layout_weight="2"
android:id="#+id/article_fragment"
android:layout_width="0dp" />
</LinearLayout>
There is a public method in my ArticleFragment which takes a string to update the content of the textview of itself:
public void updateView(String article) {
TextView view = (TextView) getActivity().findViewById(R.id.article_s);
try{
view.setText(article);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
After all the views are created, I call the updateView method from my MainActivity. But I get a NullPointerException when I try to find the article TextView. I have tried cleaning, changing the TextView's resource id.
However I have found a solution for this problem. I don't know why but it seems to work when I wrap TextView with a LinearLayout in the fragment_article.xml:
<LinearLayout
xmlns:android="..."
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text"
android:textSize="18sp"
android:id="#+id/article_s" />
</LinearLayout>
But I am wondering this: How can, in the tutorial samples, above code work and can't work when I wrote? I checked every code letter by letter but there is no difference between mine ant theirs. Is it because of the versions?
I'm working with the API 23 which is marshmallow.
Make sure you fragment is attached to the activity before calling updateView
this
TextView view = (TextView) getActivity().findViewById(R.id.article_s);
will give you NPE cause it does not belong to the activity
The views belong to the Fragments in which case you do
View view = inflater.inflate(R.layout.fragment_layout, container, false);
TextView textView = (TextView) view.findViewById(R.id.article_s);
Specifically, the fragment can access the Activity instance with getActivity() and easily perform tasks such as find a view in the activity layout:
Read Communicating with activity # https://developer.android.com/guide/components/fragments.html
So you use getActivity to find views that belong to activity which is not the case in your code.
Edit -
Wrapping it with a LinearLayout should not make any difference as it is just a viewgroup. If you just need a single textview no need for LinearLayout.
Read the accepted answer at : Difference between getActivity() and view in Fragment
use this code : you given wrong id to on TextView
TextView view = (TextView) getActivity().findViewById(R.id.article_s);
This is return NPE because your try to find the wrong id.
There are two different way you can resolve issue.
1) First one
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text"
android:textSize="18sp"
android:id="#+id/article"/>
TextView view = (TextView) getActivity().findViewById(R.id.article);
Another way keep your XML as it is & try to do below change in java code.
2) Second One
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Some Text"
android:textSize="18sp"
android:id="#+id/article_s"/>
TextView view = (TextView) getActivity().findViewById(R.id.article_s);
It doesn't work like this inside a fragment class by the way you should upload your main activity codes or your fragment class if you are using it inside the main activity, you don't need to use getActivity()
if it is inside a fragment class you need to apply it like this:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_fragment_layout_xml, container, false);
TextView AboutUs = (TextView) rootView.findViewById(R.id.id_of_textview);
I have an android activity which has three fragments and in one of the fragments I am using list view to display a list. The list can be long and the view needs to be scroll able. When the activity starts onCreateView method of all fragments is called. This is code for onCreateView method
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView;
rootView=inflater.inflate(R.layout.files, container,false);
WebService.getFiles((UsersPOJO)getArguments().getSerializable("currentUser"));
return rootView;
}
R.layout.files has listView.
The problem is when the activity starts layout of all the three fragments in that activity shrinks when a soft keypad pops up. I tried to set isScrollContainer to false on individual layout but it isn't working any solutions to this problem.
EDIT: R.layout.files
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/WhiteBackground"
android:orientation="vertical">
<ProgressBar
android:id="#+id/filesLoading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
<TextView
android:id="#+id/noFiles"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/edit_text_left_margin"
android:layout_marginRight="#dimen/edit_text_right_margin"
android:layout_marginTop="#dimen/heading_top_margin"/>
<ListView
android:id="#+id/filesListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
Take a look at windowsSoftInputMode attribute inside your AndroidMenifest.xml file. Just set windowsSoftInputMode to adjustPanin your <activity>.