Search code examples
javaandroidlistviewandroid-listfragment

Android ListFragment overlapping


I'm learning android development and I'm stuck in Fragments. I've read the tutorials point book and some android developers docs, so the next step is to build an app for my cell phone.

I'm trying to make a shopping list. When you start the app, a menu displays, it shows three options, the problematic one is the third one.

The idea is to allow the user to create update and remove products from that list.

So this's what I have done so far

product_crud.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="116dp">

    <EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/name_txt"
    android:hint="@string/product_name"
    android:inputType="text"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_add"
        android:paddingLeft="10px"
        android:text="@string/add_product"
        android:layout_below="@+id/name_txt"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true" />

</RelativeLayout>

<ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/android:list"
    android:layout_below="@+id/btn_add"
    android:layout_alignParentStart="true" />

</LinearLayout>

crudrowlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10px"
>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/btn_delete"
    android:text="@string/remove_product"
    android:layout_gravity="right"
    android:layout_alignParentTop="true"
    android:layout_alignParentEnd="true"
    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/text_name"
    android:textSize="40px"
    android:layout_alignTop="@+id/btn_delete"
    android:layout_alignParentStart="true"
    android:layout_alignBottom="@+id/btn_delete" />


 </RelativeLayout>

PM_List_Fragment

public class PM_List_Fragment extends ListFragment {

ProductsDataSource products;

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);
    products = new ProductsDataSource(getActivity());
    try {
        products.open();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    CrudArrayAdapter crudArrayAdapter = new CrudArrayAdapter(getActivity(),products.getAllProducts());
    products.close();
    setListAdapter(crudArrayAdapter);
}
}

Adapter

public class CrudArrayAdapter extends ArrayAdapter<Product> {

private final List<Product> list;
private final Activity context;

static class ViewHolder{
    protected TextView name;
    protected Button delete;
}


public CrudArrayAdapter(Activity context,List<Product> list) {
    super(context, R.layout.rowlayout,list);
    this.list = list;
    this.context = context;
}


@Override
public View getView(int position,View convertView,ViewGroup parent){
    View view;
    if(convertView == null){
        LayoutInflater inflater = context.getLayoutInflater();
        view = inflater.inflate(R.layout.crudrowlayout,null);
        final ViewHolder viewHolder = new ViewHolder();
        viewHolder.name = (TextView)view.findViewById(R.id.text_name);
        viewHolder.delete = (Button)view.findViewById(R.id.btn_delete);
        view.setTag(viewHolder);
    }else{
        view = convertView;
    }
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.name.setText(list.get(position).getName());
    return view;
}


}

and my activity

public class CrudProducts extends ListActivity {

private String msg = "Android: ";
private ProductsDataSource productsDataSource;


@Override
public void onCreate(Bundle savedInstanceState){

    super.onCreate(savedInstanceState);
  //  ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
    setContentView(R.layout.product_crud);

    PM_List_Fragment pm_list_fragment = new PM_List_Fragment();

    FragmentManager fragmentManager = getFragmentManager();

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.add(android.R.id.content,pm_list_fragment);

    Button btn_add = (Button)this.findViewById(R.id.btn_add);

    btn_add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //create a form or put some input text so we can update the db!
            EditText editText = (EditText)findViewById(R.id.name_txt);
            if(editText.getText().length() > 0 && !productsDataSource.exists(editText.getText().toString())){
                Product prod = productsDataSource.createProduct(editText.getText().toString());
             //   adapter.add(prod);

            }else{
            if(editText.getText().length() == 0 )
            {
                Toast.makeText(getApplicationContext(),"Please insert a name",Toast.LENGTH_LONG).show();
            }
            else{
                Toast.makeText(getApplicationContext(),"This product already exists",Toast.LENGTH_LONG).show();
                }
            }
          //  adapter.notifyDataSetChanged();
        }
    });

    fragmentTransaction.commit();
}

}

Don't worry about the datasource or the adapter, the problem here is that the ListView overlaps with the EditText and the Button (deleteBtn). The Listview displays above the EditText and Button. I've tried to change the layouts in different ways but none of them worked.

I've read that you can implement this same functionality with a normal activity and a ListView, but I would like to learn how to do it this way.

Some ideas?

A picture of the problem:

Problem overlap


Solution

  • Well there are a few things I noticed which might help you!

    Firstly, CrudProducts extends ListActivity and PM_List_Fragment extends ListFragment. If your intention is to show a list you should rely on ListFragment only. You could make CrudProducts extend simply an Activity.

    If you do so, you could have below layout set for CrudProducts using setContentView(R.layout.crud_activity)

    crud_activity.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" >
    
        <FrameLayout
            android:id="@android:id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </FrameLayout>
    
    </LinearLayout>
    

    Secondly, in your fragment PM_List_Fragment add

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.product_crud, container, false);
        return view;
    }
    

    Thirdly, product_crud.xml also needs some refinement

    You don't need below attributes for your <ListView> as parent of ListView is not a RelativeLayout

    android:layout_below="@+id/btn_add"
    android:layout_alignParentStart="true"
    

    Also you don't need in your childs of RelativeLayout

    android:layout_alignParentStart="true"
    android:layout_alignParentEnd="true"
    

    Instead try to make your Button to match_parent

    <Button
        android:id="@+id/btn_add"
        android:layout_width="match_parent"
    

    Also try balanced padding for your Button in dp

    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    

    Above should fix your issues and list should be visible properly.