Search code examples
androidarraylistimageviewonclicklistenercustom-adapter

Adding to ArrayList from Adapter android


I have ArrayList in class TabFragment1. I have adapter for list of installed apps. And when i click on ImageView application name and icon should go the TabFragment1 ArrayList, but i cant resolve it. Application is crashing when i click on iv.

AppAdapter

public class AppAdapter extends BaseAdapter{
    private List<ApplicationInfo> packages;
    private LayoutInflater inflater;
    private PackageManager pm;

    public AppAdapter(Context context, PackageManager pm, List<ApplicationInfo> packages) {
        this.packages = packages;
        this.pm = pm;

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    @Override
    public int getCount() {

        return packages.size();
    }

    @Override
    public ApplicationInfo getItem(int p1) {

        return packages.get(p1);
    }

    @Override
    public long getItemId(int p1) {

        return p1;
    }

    @Override
    public View getView(int position, View v, ViewGroup parent) {

        View view = null;
        final ViewHolder viewHolder;
        final TabFragment1 tab1;

        if (v == null) {
            viewHolder = new ViewHolder();
            view = inflater.inflate(R.layout.list_item, parent, false);
            viewHolder.tvAppLabel = (TextView) view
                    .findViewById(R.id.app_item_text);
            viewHolder.ivAppIcon = (ImageView) view
                    .findViewById(R.id.app_item_image);
            viewHolder.ivAppAdd = (ImageView) view
                    .findViewById(R.id.add);
            view.setTag(viewHolder);
        } else {
            view = v;
            viewHolder = (ViewHolder) view.getTag();
        }

        ApplicationInfo app = packages.get(position);
        tab1= new TabFragment1();

        viewHolder.tvAppLabel.setText(app.loadLabel(pm).toString());
        viewHolder.ivAppIcon.setImageDrawable(app.loadIcon(pm));
        viewHolder.ivAppAdd.setImageResource(R.drawable.ic_add_circle_outline_black_48dp);
        viewHolder.ivAppAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

              tab1.data.add(new AddedApps(viewHolder.ivAppIcon.getId(), 
viewHolder.tvAppLabel.getText().toString())); //trouble is here
            }
        });



        return view;
    }


    static class ViewHolder {
        private TextView tvAppLabel;
        private ImageView ivAppIcon;
        private ImageView ivAppAdd;
    }

}

TabFragment1

public class TabFragment1 extends Fragment {
    private RecyclerView rv;
    private FloatingActionButton fab;
    private Fragment installedApps;
    private FragmentTransaction transaction;
    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView.Adapter adapter;
    public List<AddedApps> data;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.tab_fragment1, container, false);

        rv=(RecyclerView) view.findViewById(R.id.recyclerView);
        fab=(FloatingActionButton) view.findViewById(R.id.fabBtn);
        installedApps = new InstalledApps();

        data=new ArrayList<AddedApps>();
        data.add(new AddedApps( R.mipmap.ic_launcher,"Application"));



        layoutManager = new LinearLayoutManager(getContext());
        rv.setLayoutManager(layoutManager);
        adapter = new AddedAppsAdapter(data);
        rv.setAdapter(adapter);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                transaction = getFragmentManager().beginTransaction();

                transaction.replace(R.id.container, installedApps);
                transaction.addToBackStack(null);

                transaction
                        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                        .commit();

    }
});



        return view;
    }


}

AddedApps

public class AddedApps {
    private int icon;
    private String name;

    public AddedApps(int icon, String name) {
        this.icon = icon;
        this.name = name;
    }

    public int getIcon() {
        return icon;
    }

    public String getName() {
        return name;
    }
}

crashlog:

java.lang.NullPointerException: Attempt to invoke interface method 'boolean java.util.List.add(java.lang.Object)' on a null object reference
         at com.kostya.newconcept.adapters.AppAdapter$1.onClick(AppAdapter.java:84)
         at android.view.View.performClick(View.java:5204)
         at android.view.View$PerformClick.run(View.java:21153)
         at android.os.Handler.handleCallback(Handler.java:739)
         at android.os.Handler.dispatchMessage(Handler.java:95)
         at android.os.Looper.loop(Looper.java:148)
         at android.app.ActivityThread.main(ActivityThread.java:5417)
         at java.lang.reflect.Method.invoke(Native Method)
         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Solution

  • Your TabFragment1 class doesn't initialize one of its members in the constructor:public List<AddedApps> data. So when you try to do tab1.data.add(...), you hit a null reference since onCreateView() hasn't been called yet and data is still null.

    Override the constructor in your TabFragment1 class and initialize that member there. Remember to call the super constructor so the Fragment class behaves normally.