[EDIT]: Thank you for all the meaningful answers, the problem is now solved, thank to your help. Similar issue: Android: I am unable to have ViewPager WRAP_CONTENT
I'm trying to implement the UI of my app : I want a ListView with a ViewPager in each row.
Here are my files :
MainActivity.java
package com.condi;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
public class MainActivity extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setListAdapter(new CardListAdapter(this, getFragmentManager()));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
CardListAdapter.java
package com.condi;
import java.util.List;
import android.app.FragmentManager;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class CardListAdapter extends BaseAdapter {
private Context context;
private FragmentManager fragmentManager;
private List<Profile> profiles;
CardListAdapter(Context context, FragmentManager fragmentManager) {
this.context = context;
this.fragmentManager = fragmentManager;
this.profiles = new DatabaseHelper(context).getProfiles();
}
#Override
public int getCount() {
return profiles.size();
}
#Override
public Profile getItem(int position) {
return profiles.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = View.inflate(context, R.layout.profile_card, null);
CardPagerAdapter mCardPagerAdapter = new CardPagerAdapter(
fragmentManager);
ViewPager viewPager = (ViewPager) convertView.findViewById(R.id.pager);
viewPager.setAdapter(mCardPagerAdapter);
viewPager.setId(R.id.pager);
return convertView;
}
}
profile_card.xml (issue came from wrap_content).
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:background="#drawable/card_background"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
CardPagerAdapter.java
package com.condi;
import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v13.app.FragmentPagerAdapter;
public class CardPagerAdapter extends FragmentPagerAdapter {
public CardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new Fragment1();
case 1:
return new Fragment2();
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
Fragment1.java
package com.condi;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
public Fragment1() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.preference_category, container, false);
}
}
Fragment2.java
package com.condi;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
public Fragment2() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.preference_category, container, false);
}
}
The database that furnishes the profiles is working well.
The problem is that I am getting an empty list with the correct number of item, but no ViewPager displayed at all. screenshot of my app
What am I doing wrong ?
Try to change your ViewPager's height in xml. wrap_content does not work.
To make is clear, its a bad practice to use viewpagers inside a list view as this design hits the ui performance. The best way to handle this problem is:
To do manual inflation of viewpagers and add to a layout.
Add a unique id to each viewpager so that it is identified uniquely by the system.
Extend a custom viewpager and onmeasure() measure the child layout inflated at the page selected. You can do this by setting a callback in your custom viewpager and trigger the callback from viewpagers onPageScrolled listener, passing the position to identify the child layout.
In your onMeaure() method measure the child layout height and set it as the viewpagers height using super.onMeasure() passing the newly measured specs.
Key points to make a note of :
N.B. Set a unique id to the viewpager inflated by you.
try this problem in layout height
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:background="#drawable/card_background"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
It's a bad practice to use wrap_content for your viewpager's height. You can use match_parent or a static dp for your viewpager's height.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginTop="4dp"
android:background="#drawable/card_background"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</FrameLayout>
If it's a must to use wrap_content for your viewpager's height you can override your viewpager's onMeasure() and calculate height. Here's an example below about it.
Android: I am unable to have ViewPager WRAP_CONTENT
I hope this'll help you.
ViewPager doesn’t support wrap_content as it stands now because it doesn’t load all of its children at the same time, meaning it can’t get an appropriate measurement. You must fix View's height in your xml or create a custom ViewPager (read more at here) and use it in your xml
Try using a fixed height ViewPager inside the ListView.ViewPager does not support wrap_content
Related
I have a RecyclerView which correctly displays data gotten from an RSS feed when it is the sole object within the XML file, i.e. it is not nested in a parent or sharing a parent within another element. Conversely, when I try to do just that, the data does not display, and I instead receive the error 'RecyclerView: No adapter attached; skipping layout' in LogCat. I should mention that this RecyclerView is generated as part of a ListFragment.
The Fragment replaces a FrameLayout in ActivityMain.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:background="#color/design_default_color_primary"
android:elevation="4dp"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:titleTextColor="#ffff"/>
<!-- This one -->
<FrameLayout
android:id="#+id/main_fragment_target"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id= "#+id/nav_view"
android:layout_width= "wrap_content"
android:layout_height= "match_parent"
android:layout_gravity= "start"
android:fitsSystemWindows= "true"
app:menu= "#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
Which is performed by the following code in MainActivity.java
MainActivity.this.runOnUiThread(() -> {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ComponentListFragment componentListFragment = new ComponentListFragment(componentsList);
transaction.replace(R.id.main_fragment_target, componentListFragment);
transaction.commit();
});
As mentioned, the data loads just fine when I'm not messing with the RecycleView XML file, so I am doubtful that inserting the fragment is the problem. I'm just posting this for posterity.
So, MainActivity.java replaces the fragment with an instance of ComponentListFragment.java:
package com.example.mclean_ross_s2030507;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
/**
* A fragment representing a list of Items.
*/
public class ComponentListFragment extends Fragment {
// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
// TODO: Customize parameters
private int mColumnCount = 1;
private ArrayList<ListComponent> components;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ComponentListFragment() {
}
public ComponentListFragment(ArrayList<ListComponent> components) {
this.components = components;
}
// TODO: Customize parameter initialization
#SuppressWarnings("unused")
public static ComponentListFragment newInstance(int columnCount) {
ComponentListFragment fragment = new ComponentListFragment();
Bundle args = new Bundle();
args.putInt(ARG_COLUMN_COUNT, columnCount);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_component_list_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
RecyclerView recyclerView = (RecyclerView) view;
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(
new DividerItemDecoration(recyclerView.getContext(),
linearLayoutManager.getOrientation())
);
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(linearLayoutManager);
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
recyclerView.setAdapter(new MyItemRecyclerViewAdapter(components));
}
return view;
}
}
Which builds a RecyclerView and sets the adapter to MyItemRecyclerViewAdapter.java:
package com.example.mclean_ross_s2030507;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.mclean_ross_s2030507.databinding.FragmentComponentListBinding;
import com.example.mclean_ross_s2030507.placeholder.PlaceholderContent.PlaceholderItem;
import java.util.ArrayList;
/**
* {#link RecyclerView.Adapter} that can display a {#link PlaceholderItem}.
* TODO: Replace the implementation with code for your data type.
*/
public class MyItemRecyclerViewAdapter extends RecyclerView.Adapter<MyItemRecyclerViewAdapter.ViewHolder> {
private final ArrayList<ListComponent> mValues;
public MyItemRecyclerViewAdapter(ArrayList<ListComponent> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(FragmentComponentListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
Log.e("MyTag", String.valueOf(holder));
holder.mItem = mValues.get(position);
// holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).getTitle());
holder.itemView.setOnClickListener(view -> {
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
// public final TextView mIdView;
public final TextView mContentView;
public ListComponent mItem;
public ViewHolder(FragmentComponentListBinding binding) {
super(binding.getRoot());
// mIdView = binding.itemNumber;
mContentView = binding.content;
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
Finally, this is the view (fragment_component_list_list.xml) I am trying to achieve, but which is causing the error:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="#+id/edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
tools:viewBindingType="androidx.recyclerview.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:name="com.example.mclean_ross_s2030507.ComponentListFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:context=".ComponentListFragment"
tools:listitem="#layout/fragment_component_list"
android:scrollbars="vertical"/>
</LinearLayout>
However, the same file with the following setup works just fine:
<androidx.recyclerview.widget.RecyclerView
tools:viewBindingType="androidx.recyclerview.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:name="com.example.mclean_ross_s2030507.ComponentListFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:context=".ComponentListFragment"
tools:listitem="#layout/fragment_component_list"
android:scrollbars="vertical"/>
Nested:
Not nested:
I'm aware that various solutions to this error are all over SO, but I'm yet to see any specifically answering my issue regarding the nesting of RecyclerView. As always, any help is much appreciated. Cheers.
The view being inflated in onCreateView of ComponentListFragment is not a RecyclerView but a LinearLayout, based on the contents of R.layout.fragment_component_list_list you provided. The parent View/ViewGroup is always returned from inflate. So you need to reference the actual RecyclerView inside of that layout:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_component_list_list, container, false);
RecyclerView rv = (RecyclerView) view.findViewById(R.id.list)
// No need for if statement, just use `rv` variable...
...
Also, your XML has a few mistakes and areas for improvement:
Remove the redundant namespace (xmlns) attributes in the RecyclerView element and move xmlns:app to the root element.
The android:name attribute is only used in the <application> element of the AndroidManifest.xml
You don't need the tools:viewBindingType attribute. It's only needed to disambiguate generated views when using View Binding Type
tools:context is only meant for the root view. See tools attributes
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="#+id/edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginRight="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/fragment_component_list"
android:scrollbars="vertical"/>
</LinearLayout>
I have a view pager with 2 views, in each view, I have a NestedScrollView which is parenting an EditText.
The first view/item in view pager scroll smoothly as I expect, but another one freezes as the way if I have never added NestedScrollView! So NestedScrollView only works for the first item.
Item :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">
<androidx.core.widget.NestedScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="#+id/edt_pager_leitner_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:enabled="false"
android:inputType="textMultiLine"
android:textColor="#color/darkGrey" />
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
View pager adapter :
package com.yasinhajilou.dileit.view.adapter.viewpager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.viewpager.widget.PagerAdapter;
import com.yasinhajilou.dileit.R;
import java.util.ArrayList;
import java.util.List;
public class AddNewLeitnerViewPagerAdapter extends PagerAdapter {
List<String> titles = new ArrayList<>();
List<String> mInformation = new ArrayList<>();
#Override
public int getCount() {
return titles.size();
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
View view = LayoutInflater.from(container.getContext()).inflate(R.layout.item_pager_leitner_info, container, false);
view.setTag(titles.get(position));
TextView textView = view.findViewById(R.id.edt_pager_leitner_info);
textView.setText(mInformation.get(position));
container.addView(view);
return view;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
if (titles.size() > 0)
return titles.get(position);
else return null;
}
public void addData(String title, String info) {
titles.add(title);
mInformation.add(info);
notifyDataSetChanged();
}
}
I am trying to implement a cube animation on my viewPager. The animation looks good on the emulator and a Samsung S8 device, but on Huawei P10 Android 7.0 it looks like in the image below:
I don't understand why the image is cropped on my Huawei device. Below is my code:
activity_main.xml
<?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"
tools:context="ro.helpproject.funcode.help.MainActivity">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
view_pager_item.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/imageView_mario"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#android:color/black"
android:src="#drawable/mario" />
CubeTransformer.java class
package ro.helpproject.funcode.help;
import android.support.v4.view.ViewPager;
import android.view.View;
public class CubeTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
view.setPivotX(position <= 0 ? view.getWidth(): 0.0f);
view.setRotationY(90f * position);
}
}
MainActivity.java
package ro.helpproject.funcode.help;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyViewPagerAdapter adapter = new MyViewPagerAdapter();
ViewPager pager = findViewById(R.id.pager);
pager.setPageTransformer(true, new CubeTransformer());
pager.setAdapter(adapter);
}
protected class MyViewPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 3;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
ImageView imageView = (ImageView) inflater.inflate(R.layout.view_pager_item, container, false);
container.addView(imageView);
return imageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}
How can I fix the issue?
imageview.setAdjustViewBounds(true);
imageview.setFitToScreen(true);
imageview.setScaleType(ScaleType.FIT_XY);
update.....
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/imageView_mario"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:scaleType="fitXY"
android:background="#android:color/black"
android:src="#drawable/mario" />
The best way to achieve this is to add a parent to your imageView 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:orientation="horizontal"
android:gravity="center">
<ImageView
android:id="#+id/imageView_mario"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:src="#drawable/mario" />
</LinearLayout>
Then in instantiateItem replace imageView with the LinearLayout:
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.view_pager_item, container, false);
container.addView(linearLayout);
return linearLayout;
}
This should work properly.
The reason that your solution does not work is that the viewpager tries to fill it's "pages" with the imageview that you provide from your xml, and so it is stretched and has unexpected behaviour.
I'm using slidemenu in my project.
In my fragment i have a listview that reads some data from db.
My fragment:
package ir.monocode.azmooneEstekhdami;
import ir.monocode.azmoonEstekhdami.R;
import java.util.ArrayList;
import android.app.Fragment;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;
public class QuestionsFragment extends Fragment {
public QuestionsFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_questions, container, false);
/******** Take some data in Arraylist ( CustomListViewValuesArr ) ***********/
// setListData();
// CustomListViewValuesArr.clear();
MySQLiteHelper db = new MySQLiteHelper(getActivity());
ArrayList<CatsModel> CustomListViewValuesArr = db.getAllCelebs();
Resources res = getResources();
// now you must initialize your list view
ListView listview = (ListView) view.findViewById(R.id.listView1);
//listview.setFastScrollEnabled(true);
/**************** Create Custom Adapter *********/
CustomAdapter adapter = new CustomAdapter(getActivity(),CustomListViewValuesArr, res);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
// do things with the clicked item
Toast.makeText(getActivity(), ""+ position, Toast.LENGTH_LONG).show();
}
});
return view;
}
}
My fragment layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dedede"
android:orientation="vertical" >
<ImageView
android:id="#+id/cimageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/top"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp" >
</ListView>
</LinearLayout>
But when i want to use onitemclicklistener it doesn`t work. Where is my problem?
As you can see i use customapater and
public void onItemClick(int mPosition) {
// TODO Auto-generated method stub
}
in my main activity.
You need to add these properties for your custom list item row layout widgets which is already inflated in getView() method by you.
android:focusable="false"
android:focusableInTouchMode="false"
I am trying to navigate from one fragment to another. These two fragments are 100% different, there is no ViewPager or something like that to connect them. Here is the code.
fragment_view1.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/firstView">
<TextView
android:id="#+id/viewOneText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="92dp"
android:layout_marginTop="182dp"
android:text="First View"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/viewOneBtn"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/viewOneText"
android:layout_below="#+id/viewOneText"
android:layout_marginTop="17dp"
android:text="Click Here" />
<include layout = "#layout/drop_down"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_alignParentBottom="true"/>
<FrameLayout
android:id="#+id/fragment_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
custom_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/customFragment" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="174dp"
android:text="Custom Fragment"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
FirstView.java (uses fragment_view1.xml)
package com.example.fragmenttest;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class FirstView extends DropDownMenu
{
private TextView firstText;
private Button btn;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_view1,container,false);
firstText = (TextView)view.findViewById(R.id.viewOneText);
btn = (Button)view.findViewById(R.id.viewOneBtn);
btn.setOnClickListener(new ButtonEvent());
return view;
}
private class ButtonEvent implements OnClickListener
{
#Override
public void onClick(View v)
{
// Create new fragment and transaction
Fragment newFragment = new CustomView();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_view, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
}
CustomView.java (uses custom_view.xml)
package com.example.fragmenttest;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class CustomView extends Fragment
{
private TextView secondText;
private Button secondViewBtn;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.custom_view,container,false);
return view;
}
}
In FirstView.java, when I click on the button, I need to move to the Fragment CustomView. But instead moving, it simply replaces everything in CustomView on top of FirstView. Below images will explain it better.
FirstView alone
CustomView alone
When the button is FirstView clicked
Why it is happening like this?
You are trying to replace firstView with the new fragment, but firstView is not a fragment, its' a RelativeLayout.
You cannot replace a fragment defined statically in the layout file. You can only replace fragments that you added dynamically via a FragmentTransaction.
None of your Layout contains fragment in layout.
<fragment
android:id="#+id/fragment1"
android:layout_width="march_parent"
android:layout_height="match_parent"></fragment>
A new Fragment will replace an existing Fragment that was previously added to the container.
Take look on this.
If you need to replace one fragment with another then fallow undermentioned :
TalkDetail fragment = new TalkDetail();
// TalkDetail is name of fragment which you need to put while replacing older one.
Bundle bundle = new Bundle();
bundle.putString("title", m_ArrayList.get(arg2).title);
bundle.putString("largeimg", m_ArrayList.get(arg2).largeimg);
bundle.putString("excert", m_ArrayList.get(arg2).excert);
bundle.putString("description", m_ArrayList.get(arg2).description);
bundle.putString("cat", m_ArrayList.get(arg2).cat);
bundle.putString("header_title", "Talk");
//bundle.putInt("postid", m_ArrayList.get(arg2).postid);
fragment.setArguments(bundle); ((BaseContainerFragment)getParentFragment()).replaceFragment(fragment, true);
Here's your BaseContainerFragment.java class that will manage a lot of stuff for you.
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import app.drugs.talksooner.R;
public class BaseContainerFragment extends Fragment {
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.container_framelayout, fragment);
transaction.commit();
getChildFragmentManager().executePendingTransactions();
}
public boolean popFragment() {
Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
boolean isPop = false;
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
return isPop;
}
}
For more specific details find my complete post over here ..
Dynamically changing the fragments inside a fragment tab host?