ArrayAdapter additions not showing in ListView - java

I have a Android fragment containing a ListView, and I have attached an ArrayAdapter to the ListView, but when I insert items into the ArrayAdapter, the ListView only shows the first item.
onCreateView iterates over my Technologies, if they're unlocked, it adds them to the ArrayList shownTechs, but only the first item ever appears
public class TabTechnologyList extends Fragment {
private static final String TAB_NAME = "tab_name";
private ListView techList;
private ArrayList<Technology> shownTechs = new ArrayList<>();
ArrayAdapter<Technology> techListAdapter;
public TabTechnologyList() { }
public static TabTechnologyList newInstance() {
TabTechnologyList fragment = new TabTechnologyList();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tabData = Globals.getTabData();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_technology_list, container, false);
techList = (ListView) view.findViewById(R.id.tabTechListList);
techListAdapter = new ArrayAdapter<>(getActivity().getApplicationContext(), R.layout.layout_techlist_element, shownTechs);
techList.setAdapter(techListAdapter);
for(Technology tech: tabData.getTechnologies()) {
shownTechs.add(tech);
}
//Only the first one is shown on the screen
return view;
}
}
}
When I google for similar issues, people seem to be recreating the ArrayAdapter instead of editing the existing one, but I'm not doing that, and cant' figure out what problem remains. Any suggestions?
fragment_technology_list.xml:
<RelativeLayout 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"
tools:context="com.tbohne.kittens.front.TabTechnologyList"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/tabTechListList" />
</RelativeLayout>
layout_techlist_element.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</TextView>
Addition
I have just realized that this fragment is not filling the parent height, and is only tall enough to show the one entry, as if the fragment height were wrap_content. (I can't scroll it, so it appears as if there's only the one). This makes me think the nesting of fragments may be related, so here's the code that creates the fragment:
public class TabTechnology extends Fragment {
private TabTechnologyList table;
private OnFragmentInteractionListener mListener;
public TabTechnology() {}
public static TabTechnology newInstance(String tabName) {[SNIP]}
#Override public static onAttach(Activity activity) {[SNIP]}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_technology, container, false);
table = TabTechnologyList.newInstance(tabName);
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.view_table, table);
transaction.commit();
return view;
}
}
fragment_technology.xml
<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"
tools:context="com.tbohne.kittens.front.TabTechnology"
android:orientation="vertical">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/view_table"
android:layout_above="#+id/view_details" />
<View android:layout_width="match_parent"
android:layout_height="1px"
android:background="?android:attr/listDivider" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/view_details"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true" />
</LinearLayout>

Putting the Fragment inside the ScrollView was the source of the problem. Simply replaced those with FrameLayout, and suddenly everything magically works. Very strange.
I suspect the problem has something to do with nesting scrollable objects.

Related

RecyclerView not calling getItemCount

I've investigated several SO answers on this question (here, here, and here) and none of the proposed solutions have worked. My problem is that my RecyclerView list items aren't being displayed. I've set breakpoints in MessengerRecyclerAdapter, onCreateViewHolder, onBindViewHolder, and getItemCount and only the first one is ever called. While in a breakpoint I've entered the expression evaluator and executed
MessengerRecyclerAdapter.getItemCount();
And received the expected answer of 20. The RecyclerView itself takes up the intended content area as demonstrated by the screenshot below (I turned the RecyclerView magenta to highlight the space it occupies).
My RecyclerView XML code is below:
<?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">
<android.support.v7.widget.RecyclerView
android:id="#+id/thread_list"
android:background="#color/colorAccent"
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:name="com.jypsee.jypseeconnect.orgPicker.MessengerListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager"
tools:context="com.jypsee.jypseeconnect.orgPicker.MessengerListFragment"
tools:listitem="#layout/fragment_messenger_cell"/>
</LinearLayout>
My RecyclerView Cell XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="#color/blueText"/>
<TextView
android:id="#+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem"
android:textColor="#color/darkText"/>
</LinearLayout>
My ListFragment class:
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
List<DummyContent.DummyItem> items = new ArrayList<>();
for (Integer i = 0; i<20; i++){
DummyContent.DummyItem item = new DummyContent.DummyItem(i.toString(),"Content","Details");
items.add(item);
}
View view = inflater.inflate(R.layout.fragment_messenger_list, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.thread_list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerAdapter = new MessengerThreadRecyclerAdapter(items, mListener);
mRecyclerView.setAdapter(mRecyclerAdapter);
mRecyclerAdapter.notifyDataSetChanged();
return view;
}
My Adapter class:
public class MessengerRecyclerAdapter
extends RecyclerView.Adapter<MessengerRecyclerAdapter.MessageThreadHolder>{
private final List<DummyItem> mValues;
private final RecyclerViewClickListener mListener;
public MessengerRecyclerAdapter(List<DummyItem> items, RecyclerViewClickListener listener) {
mValues = items;
mListener = listener;
}
#Override
public MessageThreadHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.fragment_messenger_cell, parent, false);
return new MessageThreadHolder(view);
}
#Override
public void onBindViewHolder(final MessageThreadHolder holder, final int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mListener != null) {
mListener.recyclerViewListClicked(v, position);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class MessageThreadHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public DummyItem mItem;
public MessageThreadHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.id);
mContentView = (TextView) view.findViewById(R.id.content);
}
}
}
As you can see I've set the linearLayout orientation to vertical and set the layout manager, which were the 2 most common solutions. I'm really at a loss as to what to try next, so any help is appreciated.
As I said in previous Answer edit. The issues was in your xml. The main reason it was not showing was because, You were trying to add the fragment using include tag instead of fragment tag thus respective fragment class was never getting called on the fragment layout being added to your activity.
Below is the code you needed to add the Fragment correctly.
<fragment
android:id="#+id/message_thread"
android:name="com.jypsee.jypseeconnect.orgPicker.MessengerThreadListFragment"
layout="#layout/fragment_messengerthread_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_messengerthread_list" />
And your fragment layout should be like this
<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
tools:context=".orgPicker.MessengerThreadListFragment">
<android.support.v7.widget.RecyclerView
android:id="#+id/thread_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Here is the screenshot of working
In my case , I was missing calling notifyDataSetChanged() after setting list in adapter.

TabHost inside Fragment

I'm trying to create a tabHost inside a Fragment, so I can create a tabs inside that fragment I've tried changing the extends to android.support.v4.app.Fragment but then the complete app won't build. This issue I have is the following:
wrong 2nd argument type. found'android.app.fragment' required 'android.support.v4.app.fragment'
This is the code I wrote:
public class TimeTableFragment extends Fragment {
FragmentNameFactory nameFactory = new FragmentNameFactory();
String body;
String major;
String status;
private FragmentTabHost mTabHost;
public TimeTableFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceStatus){
((MainActivity) getActivity()).setFragmentName(nameFactory.getNameNL(7));
View view = inflater.inflate(R.layout.ftimetable, container, false);
mTabHost = (FragmentTabHost) view.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.realtabcontent);
mTabHost.setup();
mTabHost.addTab(mTabHost.newTabSpec("fragmentb").setIndicator("Fragment B"));
mTabHost.addTab(mTabHost.newTabSpec("fragmentc").setIndicator("Fragment C"));
mTabHost.addTab(mTabHost.newTabSpec("fragmentd").setIndicator("Fragment D"));
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstance){
super.onViewCreated(view, savedInstance);
}
#Override
public void onActivityCreated(Bundle savedInstance){
super.onActivityCreated(savedInstance);
}}
The .xml (ftimetables):
<?xml version="1.0" encoding="utf-8"?>
<TabHost
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:id="#+id/linearLayout1"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#android:id/tabs">
</TabWidget>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#android:id/tabcontent">
</FrameLayout>
</LinearLayout>
</TabHost>
I hope someone can help me fix this issue!
change your TimeTableFragment import code
import android.app.fragment(x)
import android.support.v4.app.fragment(o)

ListFragment appearing twice on phone

I'm seeing an undesired appearance of my list fragment when I run my app on the phone emulator. On the tablet emulator it appears once but on the phone emulator it appears twice. How can I fix this error for the list to appear on the phone emulator only once?
MainActivity.java
public class MainActivity extends ActionBarActivity {
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentMainList newFragment = new FragmentMainList();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.master_container, newFragment);
transaction.commit();
if (findViewById(R.id.detail_container) != null) {
mTwoPane = true;
}
}
}
activity_main.xml
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/master_container"
android:name="com.apptacularapps.exitsexpertlondonlite.FragmentMainList"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentMainList"
tools:layout="#android:layout/list_content"/>
activity_main.xml (sw600dp)
<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:orientation="horizontal"
android:showDividers="middle"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="#+id/master_container"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:id="#+id/detail_container"/>
</LinearLayout>
FragmentMainList.java
public class FragmentMainList extends android.support.v4.app.Fragment {
ListView list_main;
String[] listContent = {
"Item 1",
"Item 2",
"Item 3"
};
private boolean mTwoPane;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.fragment_main_list, container, false);
list_main = (ListView)v.findViewById(R.id.list_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,listContent);
list_main.setAdapter(adapter);
return v;
}
}
Please move the logic to add fragment inside the if loop you have.
Although you've already understood how to make it work, I'll try to explain how to make it work properly.
What you do is in fact this:
If on small screen - add the fragment statically (in XML)
If on larger screen - add the fragment dynamically (with FragmentTransaction)
It looks weird that the method by which you get the desired functionality depend on the screen size - there should be no correlation between these factors.
What you ought to do (IMHO) is to add this fragment dynamically in both cases - just change your Fragment tag in the first XML to FrameLayout and everything will work as expected.

ListFragment: Runtime error "Your content must have a ListView whose id attribute is 'android.R.list'

I have a listfragment class:
public class activityfeedScreen extends ListFragment implements OnItemClickListener {
private ListView activityfeed_feedList_listView;
private ActivityFeedBaseAdapter adapter;
public static final activityfeedScreen newInstance()
{
activityfeedScreen fragment = new activityfeedScreen();
Bundle bdl = new Bundle(1);
fragment.setArguments(bdl);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_activityfeed_screen, container, false);
activityfeed_feedList_listView = (ListView)v.findViewById(R.id.activityfeed_feedList_listView);
activityfeed_feedList_listView.setAdapter(adapter);
activityfeed_feedList_listView.setOnItemClickListener(this);
return v;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void onItemClick(AdapterView<?> activityfeedlistview, View view, int position, long itemID) {
Intent intent_activityfeed_showitemdescription = new Intent(view.getContext(), activityfeedItemScreen.class);
startActivity(intent_activityfeed_showitemdescription);
}
}
In this class I am getting an error at the line:
activityfeed_feedList_listView = (ListView)v.findViewById(R.id.activityfeed_feedList_listView);
I initially thought it was a problem due to the getView() being null so I moved that from the onCreate method to the onCreateView() method. But I am getting the runtime error as stated in the title.
Here is my layout file:
<?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:background="#E5E5E5"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp">
<ImageView
android:id="#+id/activityfeed_profilePicture_imageView"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:src="#drawable/default_profile"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#B9B9B9"
android:layout_marginTop="20dp">
<ListView
android:id="#+id/activityfeed_feedList_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
I understand that I must change the listview id to
android:id="#android:id/list"
but I am not sure then how to call that in my onCreateView method.
Thanks for all your help!
Yes. First of all you do have to change the ID of your ListView like so:
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
In your onCreateView you can reference the ID by android.R.id.list. This is because Android built-in resource reside in android.R. You can also find there drawables, styles, etc. (you can call them in a similar maneer).
Taking the above into consideration, your onCreateView method should look like this :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_activityfeed_screen, container, false);
activityfeed_feedList_listView = (ListView)v.findViewById(android.R.id.list);
activityfeed_feedList_listView.setAdapter(adapter);
activityfeed_feedList_listView.setOnItemClickListener(this);
return v;
}
That's all ;)
In onCreateView() you need to provide a layout that has a ListView with and id of #android:id/list.
ListFragment provides some helper methods (e.g setListAdapter()) that require the layout to have a ListView with that id so it can reference it and set the adapter for you.

Fragment Not Displaying In Activity

Currently when running my application, going to this activity does not display my fragment. Am I adding the fragment wrong and so nothing in the fragment is displayed? Or is there something wrong the dynamic behavior in the fragment onCreateView method?
My Activity Code
public class AskQuestionActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask_question);
}
}
My Activity XML
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="#string/header_text"/>
<fragment android:name="com.mypackage.AskQuestionFragment"
android:id="#+id/question_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
My Fragment Code
public class AskQuestionFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String questionText = "What is your favorite color?";
List<String> answers = Arrays.asList("Red", "Blue", "Yellow");
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container);
Resources res = getResources();
int id = res.getIdentifier("question_text", "id", layout.getContext().getPackageName());
TextView questionTextView = (TextView)layout.findViewById(id);
questionTextView.setText(questionText);
id = res.getIdentifier("question_answers", "id", layout.getContext().getPackageName());
RadioGroup radioGroup = (RadioGroup)layout.findViewById(id);
Collections.reverse(answers);
for (String s : answers) {
RadioButton button = new RadioButton(layout.getContext());
button.setText(s);
radioGroup.addView(button, 0);
}
return layout;
}
}
My Fragment XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/question_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/question_text"/>
<RadioGroup android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/question_answers"></RadioGroup>
<Button
android:id="#+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/submit_button_text"
/>
</LinearLayout>
try to put framelayout instead of fragment in xml. and in your activity's onCreate create the instance of your fragment you want to display and add it to the fragment container
public class AskQuestionActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ask_question);
AskQuestionFragment fragment = new AskQuestionFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.id_of_your_container, fragment).commit();
}
}
Your problem might be when doing this:
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container);
Consider to replace that line with one of the following:
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, null);
or
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.question, container, false);
change your layout from linear to be framelayout, and attach your fragment in activity .
getSupportFragmentManager().beginTransaction()
.add(R.id.your_fragment_container, fragment).commit();

Categories