How to replace fragment run time - java

I want to add and replace Frame layout with fragment on fragment-1 and fragment-2 on item click of Grid and List item.
I had created main.xml class
<?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" >
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:layout_height="fill_parent" >
<fragment
android:id="#+id/fragment1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
class="com.example.fragment.Fragment1" />
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#000000" />
<fragment
android:id="#+id/fragment2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
class="com.example.fragment.Fragment2" />
</LinearLayout>
<View
android:layout_width="1dp"
android:layout_height="fill_parent"
android:background="#000000" />
<FrameLayout
android:id="#+id/fragment3"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="2"/>
Here is my fragment_1.xml
<?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:paddingLeft="8dp"
android:paddingRight="8dp" >
<GridView
android:id="#+id/Grid1"
android:layout_width="match_parent"
android:numColumns="auto_fit"
android:columnWidth="100dp"
android:layout_height="0dp"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
and here is my row_fragment1_list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="15dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/img_view"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#CCCCCC"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
and fragment_3.xml
<?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:gravity="center"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_fragment3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22sp"
android:gravity="center"
android:text="This is 3rd Fragment" />
and here is my Main.xml
public class Main extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
and here is Fragment1.class
public class Fragment1 extends Fragment implements OnItemClickListener
{
Activity myActivity;
GridView mGridView;
private String ListItem[] = {"Item 1","Item 2","Item 3","Item 4","Item 5","Item 6","Item 7"};
private int imgID[] = {R.drawable.admin_access_rule,
R.drawable.admin_backup,R.drawable.admin_browsesite,
R.drawable.admin_comment_post,R.drawable.admin_content,
R.drawable.admin_content_type,R.drawable.admin_logout,};
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
this.myActivity = activity;
Toast.makeText(activity.getApplicationContext(), "On Attach", Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Toast.makeText(myActivity.getApplicationContext(), "On Create", Toast.LENGTH_SHORT).show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Create View", Toast.LENGTH_SHORT).show();
View view = inflater.inflate(R.layout.fragment_1,container, false);
mGridView = (GridView)view.findViewById(R.id.Grid1);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Activity Created", Toast.LENGTH_SHORT).show();
super.onActivityCreated(savedInstanceState);
}
#Override
public void onStart()
{
super.onStart();
mGridView.setAdapter(new GridBaseAdapter(myActivity));
mGridView.setOnItemClickListener(this);
}
private class GridBaseAdapter extends BaseAdapter
{
LayoutInflater mLayoutInflater = null;
public GridBaseAdapter(Context mContext)
{
mContext = myActivity;
mLayoutInflater = LayoutInflater.from(mContext);
}
#Override
public int getCount()
{
return ListItem.length;
}
#Override
public Object getItem(int position)
{
return null;
}
#Override
public long getItemId(int position)
{
return ListItem.length;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if(convertView == null)
{
convertView = mLayoutInflater.inflate(R.layout.row_fragment_list, null);
}
ImageView mImageView = (ImageView) convertView.findViewById(R.id.img_view);
mImageView.setImageResource(imgID[position]);
TextView tvUserEmail = (TextView) convertView.findViewById(R.id.text2);
tvUserEmail.setText("Sub " +ListItem[position]);
return convertView;
}
}
#Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id)
{
TextView txt3 = (TextView)myActivity.findViewById(R.id.tv_fragment3);
txt3.setText("1st Fragment's : " + position +" Item Clicked");
}
}
My Fragment2.class
public class Fragment2 extends ListFragment
{
Activity myActivity;
private String ListItem[] = {"Item 1","Item 2","Item 3","Item 4","Item 5","Item 6","Item 6","Item 7"};
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
this.myActivity = activity;
Toast.makeText(activity.getApplicationContext(), "On Attach", Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Toast.makeText(myActivity.getApplicationContext(), "On Create", Toast.LENGTH_SHORT).show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Create View", Toast.LENGTH_SHORT).show();
/** Creating an array adapter to store the list of countries **/
ArrayAdapter<String> adapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1,ListItem);
/** Setting the list adapter for the ListFragment */
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Activity Created", Toast.LENGTH_SHORT).show();
super.onActivityCreated(savedInstanceState);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
Toast.makeText(myActivity.getApplicationContext(), position +" Item Clicked", Toast.LENGTH_SHORT).show();
TextView txt3 = (TextView)myActivity.findViewById(R.id.tv_fragment3);
txt3.setText("2nd Fragment's : " + position +" Item Clicked");
super.onListItemClick(l, v, position, id);
}
}
And Last my Fragment3.class
public class Fragment3 extends Fragment
{
Activity myActivity;
TextView txt_view;
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
this.myActivity = activity;
Toast.makeText(activity.getApplicationContext(), "On Attach", Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Toast.makeText(myActivity.getApplicationContext(), "On Create", Toast.LENGTH_SHORT).show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Create View", Toast.LENGTH_SHORT).show();
View view = inflater.inflate(R.layout.fragment_3,container, false);
txt_view = (TextView)view.findViewById(R.id.tv_fragment3);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
Toast.makeText(myActivity.getApplicationContext(), "On Activity Created", Toast.LENGTH_SHORT).show();
super.onActivityCreated(savedInstanceState);
}
}

Make fragments expose interface that your activity can attach itself to. The event should occur when desired (e.g. list item is clicked). Then, activity should place instance of the fragment where it should be, for example:
// fragment is an instance of the fragment you want to show
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment3, fragment);
transaction.commit();

Related

AndroidTv Leanback - ArrayObjectAdapter crashes on null object reference

Trying to use LeanbackTabLayout & LeanbackViewPager to create top navigation in my AndroidTv app, but somehow my rowsAdapter is null & crashes on setAdapter. When I debug, I see that the ListRow is not null. What am I doing wrong?
HomeActivity:
public class HomeActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
LeanbackTabLayout leanbackTabLayout = ActivityCompat.requireViewById(this, R.id.tablayout);
leanbackTabLayout.setFocusable(true);
LeanbackViewPager leanbackViewPager = ActivityCompat.requireViewById(this, R.id.viewpager);
TablayoutAdapter adapter = new TablayoutAdapter(getSupportFragmentManager(), 3);
leanbackViewPager.setAdapter(adapter);
leanbackTabLayout.setupWithViewPager(leanbackViewPager);
}
}
TablayoutAdapter:
public class TablayoutAdapter extends FragmentStatePagerAdapter {
int tabCount;
public TablayoutAdapter(#NonNull FragmentManager fm, int tabCount) {
super(fm);
this.tabCount = tabCount;
}
#NonNull
#Override
public Fragment getItem(int position) {
return new HomeFragment();
}
#Override
public int getCount() {
return tabCount;
}
}
HomeActivity xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeActivity">
<androidx.leanback.tab.LeanbackTabLayout
android:id="#+id/tablayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:nextFocusDown="#id/viewpager"
/>
<androidx.leanback.tab.LeanbackViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
HomeFragment:
public class HomeFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListRowPresenter lrp = new ListRowPresenter();
final CardPresenter cardPresenter = new CardPresenter();
ArrayObjectAdapter rowsAdapter = new ArrayObjectAdapter(lrp);
for (int i = 0; i < 3; ++i) {
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(cardPresenter);
listRowAdapter.add(new Navigation("Tab1"));
listRowAdapter.add(new Navigation("Tab2"));
listRowAdapter.add(new Navigation("Tab3"));
HeaderItem header = new HeaderItem(i, "Row " + i);
System.out.println(header);
System.out.println("hello");
rowsAdapter.add(new ListRow(header, listRowAdapter));
}
RowsSupportFragment rowsSupportFragment = (RowsSupportFragment) getChildFragmentManager().findFragmentById(R.id.row1);
System.out.println(rowsAdapter);
System.out.println("hello");
rowsSupportFragment.setAdapter(rowsAdapter);
}
}
HomeFragment xml:
<?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:layout_height="match_parent">
<FrameLayout
android:id="#+id/row1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

Recyclerview is null through whole lifecycle

I have a problem that is driving me nuts and been searching several hours around the web but cant find a solution. I want to set an animation on the first view in my recyclerview when I add new data to the list. But I cant because the recyclerview is null.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
orientation = getResources().getConfiguration().orientation;
model = ViewModelProviders.of(getActivity()).get(ViewModelAdvices.class);
model.getAdvices().observe(this, new Observer <List <Advice>>() {
//Update recyclerview automatically when data is changed
#Override
public void onChanged(List <Advice> advices) {
filtered_advices_list.clear();
filtered_advices_list.addAll(advices);
adapter_recycler_view.notifyDataSetChanged();
}
});
}
#Override
public void onResume() {
super.onResume();
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.test_item);
View v = recycler_view.getChildAt(0);
v.startAnimation(animation);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.show_advices_fragment, container, false);
setupLayoutDifferences(view);
recycler_view = (RecyclerView) view.findViewById(R.id.recycler_view);
layout_manager = new LinearLayoutManager(getContext());
recycler_view.setLayoutManager(layout_manager);
adapter_recycler_view = new AdapterRV(filtered_advices_list);
recycler_view.setAdapter(adapter_recycler_view);
spinner_1 = (Spinner) view.findViewById(R.id.spinner_1);
adapter_spinner_1 = ArrayAdapter.createFromResource(view.getContext(), R.array.categories, android.R.layout.simple_spinner_item);
adapter_spinner_1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_1.setAdapter(adapter_spinner_1);
spinner_1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView <?> parent, View view, int position, long id) {
String category = spinner_1.getItemAtPosition(spinner_1.getSelectedItemPosition()).toString();
model.setCategory(category);
}
#Override
public void onNothingSelected(AdapterView <?> parent) { }
});
return view;
}
}
show_advices_fragment
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/colorBlueGreen"
android:paddingBottom="6dp">
<Spinner
android:id="#+id/spinner_1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:backgroundTint="#color/colorBlack" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<Button
android:id="#+id/button_add_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:visibility="gone"
android:text="#string/button_add_activity" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/button_add_activity"
android:background="#color/colorLightGrey"
android:scrollbars="vertical"
/>
</RelativeLayout>
</LinearLayout>
list_item_activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#color/colorWhite"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:weightSum="3">
<TextView
android:id="#+id/text_view_advice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border"
android:textColor="#color/colorPrimary"
android:paddingRight="4dp"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="#+id/text_view_author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/colorGrey"
android:layout_weight="2"
android:gravity="center"
android:text="TextView" />
</LinearLayout>
And test_item
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="#android:integer/config_longAnimTime">
<translate
android:interpolator="#android:anim/decelerate_interpolator"
android:fromXDelta="100%p"
android:toXDelta="0"
/>
<alpha
android:fromAlpha="0.5"
android:toAlpha="1"
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
/>
</set>
In the onResume I am in the last lifecycle I suppose and the recyclerview is being build up already in onCreateView. I guess that the build-up of the recyclerview aint finished before I reach onResume, but how can I solve this?
If I do the animation with a mouseclick when the fragment is already loaded it works but not when I switch fragment and the recyclerview is being built up again.
Try this
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
orientation = getResources().getConfiguration().orientation;
model = ViewModelProviders.of(getActivity()).get(ViewModelAdvices.class);
model.getAdvices().observe(this, new Observer<List<Advice>>() {
//Update recyclerview automatically when data is changed
#Override
public void onChanged(List<Advice> advices) {
filtered_advices_list.clear();
filtered_advices_list.addAll(advices);
}
});
}
#Override
public void onResume() {
super.onResume();
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.test_item);
View v = recycler_view.getChildAt(0);
v.startAnimation(animation);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.show_advices_fragment, container, false);
setupLayoutDifferences(view);
recycler_view = (RecyclerView) view.findViewById(R.id.recycler_view);
layout_manager = new LinearLayoutManager(getContext());
recycler_view.setLayoutManager(layout_manager);
populateAdapter();
spinner_1 = (Spinner) view.findViewById(R.id.spinner_1);
adapter_spinner_1 = ArrayAdapter.createFromResource(view.getContext(), R.array.categories, android.R.layout.simple_spinner_item);
adapter_spinner_1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_1.setAdapter(adapter_spinner_1);
spinner_1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String category = spinner_1.getItemAtPosition(spinner_1.getSelectedItemPosition()).toString();
model.setCategory(category);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
if (adapter_recycler_view != null){
adapter_recycler_view.notifyDataSetChanged();
}
return view;
}
private void populateAdapter() {
adapter_recycler_view = new AdapterRV(filtered_advices_list);
recycler_view.setAdapter(adapter_recycler_view);
}
You can't depends on onResume() in Fragment, because it's not 100% called after onCreateView() on some Android versions (More details at Fragment onResume() & onPause() is not called on backstack). So, there is a probability that you're fragment layout creation is not yet finished.
You can wait until the RecyclerView is finished inflating all the items with OnGlobalLayoutListener then show the animation for the first item:
recycler_view.getViewTreeObserver()
.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// show the animation
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.test_item);
View v = recycler_view.getChildAt(0);
v.startAnimation(animation);
// remove listener so that this won't be called multiple time.
recycler_view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
Thank you for trying to help me. Problem is that my application is probably not the best organized so everything runs before my recyclerview is done with the list it gets from ViewModel. But doing the animation on a separate thread works like a charm, then I also have full control over the animation.
if(action.equals("addData")) {
Thread thread = new Thread() {
#Override
public void run() {
try {
boolean recycler_view_loading = true;
while(recycler_view_loading ) {
sleep(250);
if (recycler_view.getChildAt(0) != null) {
Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.item_animation_side);
View v = recycler_view.getChildAt(0);
v.startAnimation(animation);
recycler_view_loading = false;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}

RecyclerView No adapter attached

There is an activity with container for fragments, which with a start of activity added ViewPagerFragment. There is a RecyclerView inside of MainFragment (which is tab) which is displayed but not filled with a data.
Tried to change width and high from 0 to Match_Parent and Fixed_Size. Also changed ConstraintLayout to RelativeLayout.Using theme android:theme="#style/MyMaterialTheme"
style.xml
<style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="MyMaterialTheme" parent="MyMaterialTheme.Base">
</style>
E/RecyclerView: No adapter attached; skipping
MainActivity.class
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private AdView mAdView;
private FragmentTransaction mFragmentTransaction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdView = (AdView) findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
mAdView.loadAd(adRequest);
mFragmentTransaction = getSupportFragmentManager()
.beginTransaction()
.add(R.id.container_frame, new ViewPagerFragment());
mFragmentTransaction.commit();
}
#Override
protected void onResume() {
super.onResume();
mAdView.resume();
}
#Override
protected void onPause() {
super.onPause();
mAdView.pause();
}
#Override
protected void onDestroy() {
mAdView.destroy();
super.onDestroy();
}
activity_main.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimaryDark"
tools:context="com.newakkoff.justad.Activities.MainActivity">
<RelativeLayout
ads:layout_constraintBottom_toTopOf="#+id/adView"
ads:layout_constraintTop_toTopOf="parent"
ads:layout_constraintLeft_toLeftOf="parent"
ads:layout_constraintRight_toRightOf="parent"
android:id="#+id/container_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
<com.google.android.gms.ads.AdView
android:id="#+id/adView"
android:layout_width="0dp"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
tools:layout_constraintRight_creator="1"
tools:layout_constraintLeft_creator="1"
android:layout_height="50dp">
</com.google.android.gms.ads.AdView>
</android.support.constraint.ConstraintLayout>
ViewPagerFragment.class
public class ViewPagerFragment extends Fragment {
private ViewPager mViewPager;
private Toolbar mToolbar;
private TabLayout mTableLayout;
int i = 1;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_view_pager, container, false) ;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager_main);
mViewPager.setAdapter(new CustomPagerAdapter(getActivity()));
mViewPager.setCurrentItem(1);
mTableLayout = (TabLayout) view.findViewById(R.id.tabs);
mTableLayout.setupWithViewPager(mViewPager);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
}
}
fragment_view_pager.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:id="#+id/appBarLayout"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager_main"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="0dp"
android:layout_height="0dp">
MainFragment.class
public class MainFragment extends Fragment {
private RecyclerView mRecyclerView;
private MyAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLayoutManager = new LinearLayoutManager(this.getActivity(),LinearLayoutManager.VERTICAL,false);
mAdapter = new MyAdapter(new String[]{"test one", "test two", "test three", "test four", "test five", "test six", "test seven"});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.rv_recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
fragment_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="8dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp"
tools:listitem="#layout/card_item"
android:background="#color/colorPrimary"/>
</android.support.constraint.ConstraintLayout>
CustomPageAdapter.class
public class CustomPagerAdapter extends PagerAdapter {
private Context mContext;
public CustomPagerAdapter(Context context) {
mContext = context;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ModelPager modelsPager = ModelPager.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(modelsPager.getLayoutResId(), container, false);
container.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return ModelPager.values().length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
ModelPager customPagerEnum = ModelPager.values()[position];
return mContext.getString(customPagerEnum.getTitleResId());
}
}
ModelPager.class
public enum ModelPager {
SEND_FRAGMENT(R.string.send_fragment_tab,R.layout.fragment_send),
MAIN_FRAGMENT(R.string.main_fragment_tab, R.layout.fragment_main),
ABOUT_FRAGMENT(R.string.about_fragment_tab, R.layout.fragment_about);
private int mTitleResId;
private int mLayoutResId;
ModelPager(int titleResId, int layoutResId) {
mTitleResId = titleResId;
mLayoutResId = layoutResId;
}
public int getTitleResId() {
return mTitleResId;
}
public int getLayoutResId() {
return mLayoutResId;
}
}
MyAdapter.class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
static class MyViewHolder extends RecyclerView.ViewHolder {
private static final String TAG = "My Recycler Adapter";
CardView mCardView;
TextView mTextView;
MyViewHolder(View v) {
super(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Element " + getAdapterPosition() + " clicked.");
}
});
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_text);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter( String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
// set the view's size, margins, paddings and layout parameters
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mTextView.setText(mDataset[position]);
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
card_item.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="68dp" >
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="62dp"
card_view:cardCornerRadius="4dp"
card_view:elevation="14dp">
<TextView
android:id="#+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:gravity="center" >
</TextView>
</android.support.v7.widget.CardView>
</RelativeLayout>
The only place that can logically have anything to do with that error is mRecyclerView.setAdapter(mAdapter); since its the only RecyclerView.
Looking at the documentation mAdapter is allowed to be null to represent no adapter. So either that variable is null or it is does not properly implement the RecyclerView.Adapter interface.

setOnItemClickListener not working

My Listview app gets its data and background color of itemview from custom adapter ListAdapter.class.i also need to set the currently selected list items value in a textview below listview,but the setOnItemClickListener in MAinActivity is not executing.pls help.
This is my list view app:
Layout image
MainActivity.java
public class MainActivity extends Activity {
private static ListAdapterclass adapter;
ListView lv;
TextView tv2;
private final String android_versions[]={
"Donut",
"Eclair",
"Froyo",
"Gingerbread",
"Honeycomb",
"Ice Cream Sandwich",
"Jelly Bean",
"KitKat",
"Lollipop",
"Marshmallow"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
lv = (ListView) findViewById(R.id.listView1);
tv2 = (TextView) findViewById(R.id.selected);
adapter = new ListAdapterclass(getApplicationContext(), android_versions);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), "hiiiiiiiii", Toast.LENGTH_SHORT).show();
System.out.println("********************** INSIDE ONITEMCLICKLISTNER IN MAIN ACTIVITY ******************");
String ver_name = (lv.getItemAtPosition(i)).toString();
tv2 = (TextView) findViewById(R.id.selected);
tv2.setText(ver_name);
}
});
}
}
ListAdapter.class
public class ListAdapterclass extends ArrayAdapter implements AdapterView.OnItemClickListener{
private String android_versionNames[];
Context mContext;
public int row_index=-1;
#Override
public void onItemClick(AdapterView<?> adapterView, View v, int i, long l) {
int position=(Integer)v.getTag();
String ver_name=getItem(position).toString();
}
private static class ViewHolder{
TextView tv;
LinearLayout LL;
TextView tv2;
}
public ListAdapterclass(Context context,String android_versionnames[]) {
super(context, R.layout.list_item,android_versionnames);
this.android_versionNames=android_versionnames;
this.mContext=context;
System.out.println(" ???????????????????????? Inside dataadapter,Android names : ?????????????????????????????\n ");
for(int i=0;i<android_versionnames.length;i++){
System.out.println("\n"+android_versionnames[i]);
}
}
private int lastPosition=-1;
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
String ver_name=getItem(position).toString();
final ViewHolder viewHolder;
final View result;
if(convertView==null){
viewHolder=new ViewHolder();
LayoutInflater inflater=LayoutInflater.from(getContext());
convertView=inflater.inflate(R.layout.list_item,parent,false);
viewHolder.tv=(TextView)convertView.findViewById(R.id.label);
viewHolder.LL=(LinearLayout) convertView.findViewById(R.id.linearLayout_1);
viewHolder.tv2=(TextView)convertView.findViewById(R.id.selected);
result=convertView;
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder) convertView.getTag();
result=convertView;
}
lastPosition=position;
viewHolder.tv.setText(ver_name);
viewHolder.LL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
row_index=position;
notifyDataSetChanged();
}
});
if(row_index==position){
viewHolder.LL.setBackgroundColor(Color.parseColor("#409de1"));
viewHolder.tv.setTextColor(Color.parseColor("#ffffff"));
}
else
{
viewHolder.LL.setBackgroundColor(Color.parseColor("#ffffff"));
viewHolder.tv.setTextColor(Color.parseColor("#000000"));
}
return convertView;
}
}
ActivityMain.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:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.cybraum.test.listviewcolorchange.MainActivity"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:clickable="true"
android:layout_weight="1"
>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView1"
>
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".2"
android:id="#+id/linearLayout_2"
android:orientation="horizontal"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Selected : "
android:textStyle="bold"
android:layout_gravity="center"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="text"
android:id="#+id/selected"
android:layout_gravity="center"/>
</LinearLayout>
</LinearLayout>
listitem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="#+id/linearLayout_1"
android:padding="10dp">
<TextView
android:id="#+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dip"
android:textSize="16dip"
android:textStyle="bold"
android:textColor="#000000"
android:gravity="center">
</TextView>
</LinearLayout>
what is the problem?
Remove viewHolder.LL.setOnClickListener listener from adapter and
In your adapter add a method to update row_index:
public void changeIndex(int rowIndex){
this.row_index = rowIndex;
notifyDataSetChanged();
}
Call this method from onItemClickListener event:
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
adapter.changeIndex(i);//This will give you the same result of viewHolder.LL.setOnClickListener as you are doing
//Do whatever you are doing previously
}
});
If you take click event from adapter then listview itemclick could not work if you need adapter click event and listview item click please refer the link,
How to make imageView clickable from OnItemClickListener?
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long viewId = view.getId();
if (viewId == R.id.button1) {
Toast.makeText(this, "Button 1 clicked", Toast.LENGTH_SHORT).show();
} else if (viewId == R.id.button2) {
Toast.makeText(this, "Button 2 clicked", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "ListView clicked" + id, Toast.LENGTH_SHORT).show();
}
}
In adapter:
viewHolder.Btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
((ListView) parent).performItemClick(v, position, 0); // Let the event be handled in onItemClick()
}
Use:
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(getApplicationContext(), "hiiiiiiiii", Toast.LENGTH_SHORT).show();
System.out.println("********************** INSIDE ONITEMCLICKLISTNER IN MAIN ACTIVITY ******************");
String ver_name = (lv.getItemAtPosition(i)).toString();
tv2 = (TextView) findViewById(R.id.selected);
tv2.setText(ver_name);
}
});
And from adapter remove
implements AdapterView.OnItemClickListener
You need to remove your adaptor from the setOnClickListner()
Try to change Your method with
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Object o = prestListView.getItemAtPosition(position);
prestationEco str=(prestationEco)o;//As you are using Default String Adapter
Toast.makeText(getBaseContext(),str.getTitle(),Toast.LENGTH_SHORT).show();
}
});
change listview xml
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"></ListView>
remove AdapterView.OnItemClickListener from adapter class
public class ListAdapterclass extends ArrayAdapter {
}
change listview xml
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
</ListView>
remove AdapterView.OnItemClickListener from adapter class
public class ListAdapterclass extends ArrayAdapter {
}

CheckedTextView not working in custom ListView

I have created a ListView containig CheckedTextView.
I'm feeding the elements in this ListView via a custom ArrayAdapter.
the list is displayed fine, but the checkbox is not responding when I select the list item
Code:
MainActivity class:
public class MainActivity extends ListActivity {
ArrayList<String> m_list;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncHandler(this).execute();
}
public class AsyncHandler extends AsyncTask {
Context context;
public AsyncHandler(Context c) {
context = c;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "In onPreExecute()", Toast.LENGTH_SHORT)
.show();
}
#Override
protected Object doInBackground(Object... arg0) {
getList();
return null;
}
#Override
protected void onPostExecute(Object result) {
// super.onPostExecute(result);
setListAdapter(new ElementAdapter(context, m_list));
}
private void getList() {
m_list = new ArrayList<String>();
m_list.add("Ele 1");
m_list.add("Ele 2");
m_list.add("Ele 3");
m_list.add("Ele 4");
}
}
}
Adapter class
public class ElementAdapter extends ArrayAdapter implements OnClickListener {
ArrayList<String> items = new ArrayList<String>();
Context context;
CheckedTextView tvElement;
public ElementAdapter(Context c, ArrayList<String> elements) {
super(c, R.layout.row, elements);
this.items = elements;
this.context = c;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.row, parent, false);
tvElement = (CheckedTextView) view
.findViewById(R.id.ctvElements);
tvElement.setText(items.get(position));
tvElement.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.ctvElements:
if(!tvElement.isChecked()){
tvElement.setChecked(true);
tvElement.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);
}else{
tvElement.setChecked(false);
tvElement.setCheckMarkDrawable(android.R.drawable.checkbox_off_background);
}
notifyDataSetChanged();
}
}
}
Row layout:
<?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">
<CheckedTextView android:id="#+id/ctvElements"
android:paddingLeft="20dip" android:paddingRight="20dip"
android:paddingTop="10dip" android:paddingBottom="10dip"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical" android:checkMark="#android:drawable/checkbox_off_background"
android:focusable="false" />
<!-- <CheckBox android:id="#+id/checkBox1" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:focusable="false" /> <TextView
android:id="#+id/tvElement" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Element" android:textSize="25sp" /> -->
</LinearLayout>
If you only want to add checkmarks to each row then use ListView.setChoiceMode(). The checkmarks will respond to a click anywhere in the row without adding any onClickListeners or custom Adapters.
Add this to your onCreate:
ListView listView = (ListView) findViewById(android.R.id.list);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Then use the built-in ArrayAdapter:
#Override
protected void onPostExecute(Object result) {
// super.onPostExecute(result);
setListAdapter(new ArrayAdapter<String>(context, R.layout.row, m_list));
}
You can use the default checked row layout with android.R.layout.simple_list_item_checked.
Otherwise if you want some customization the ListView rows change row.xml to this:
<CheckedTextView android:id="#android:id/text1"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_width="fill_parent"
android:checkMark="#android:drawable/checkbox_off_background"
android:gravity="center_vertical"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:paddingTop="10dip"
android:paddingBottom="10dip"
/>

Categories