drag-sort-listview icon indicating copy to clipboard operation
drag-sort-listview copied to clipboard

Layout issue when large amount of data present

Open axelsegers opened this issue 13 years ago • 10 comments

We have a layout issue on the last element of the LIST

It only occurs when the list is populated with a large number of items.

In this case the height of the last element is to narrow to display it's content.

Can this issue be fixed ?

axelsegers avatar Oct 16 '12 12:10 axelsegers

Hm. Curious. How many items is "large"?

Is there anything special about your last item?

bauerca avatar Oct 16 '12 20:10 bauerca

I'd have to take a look at your XML to make any further guesses. Can you post? DSLV and item layout preferably. Thanks!

bauerca avatar Oct 17 '12 07:10 bauerca

Also. Do things work correctly in a regular ListView?

bauerca avatar Oct 17 '12 07:10 bauerca

I don't see your code. Are you sure you sent it?

bauerca avatar Oct 17 '12 18:10 bauerca

Drat, I still don't see your code. Are you pasting directly into a GitHub comment box?

bauerca avatar Oct 19 '12 19:10 bauerca

package be.test.view.settings;

import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView;

import be.test.android.R; import be.test.android.model.IProduct; import be.test.android.presenter.settings.products.ProductVisibility; import be.test.android.util.AlertDialogHelper; import be.test.android.util.MetricHelper; import be.test.android.util.TypefaceHelper; import be.test.android.util.TypefaceManager.TypefaceName; import be.test.android.view.AbstractLinearLayout; import be.test.android.view.settings.DragSortListView.DropListener; import be.test.android.widget.Switch;

import java.util.ArrayList; import java.util.List;

public class ProductsListView extends AbstractLinearLayout {

private final DragSortListView mListView;
private final TextView mTitleLabel;

private ProductAdapter mAdapter;
private boolean mHasChanged;
private boolean mShouldHaveAtLeastOneSelected;

public ProductsListView(Context context, SettingsProductOrderView parent) {
    super(context);
    setContentView(R.layout.settings_product_order_list);
    setOrientation(VERTICAL);
    setClipToPadding(false);
    setPadding(toDp(8), toDp(8), toDp(8), toDp(8));
    mTitleLabel = (TextView) findViewById(R.id.titleLabel);
    mListView = (DragSortListView) findViewById(android.R.id.list);
    TypefaceHelper.applyTypeface(TypefaceName.ROBOTO_REGULAR, mTitleLabel);
}

private DropListener mDropListener = new DropListener() {
    @Override
    public void drop(int from, int to) {
        mAdapter.moveData(from, to);
        mAdapter.notifyDataSetChanged();
        mHasChanged = true;
    }
};

public void setTitle(String title) {
    mTitleLabel.setText(title);
}

public void setShouldHaveAtLeastOneSelected(boolean atLeastOne) {
    mShouldHaveAtLeastOneSelected = atLeastOne;
}

public void setProducts(List<ProductVisibility> products) {
    ArrayList<ProductVisibility> mProducts = new ArrayList<ProductVisibility>(products);
    mAdapter = new ProductAdapter(mProducts);
    mListView.setAdapter(mAdapter);

    int rowHeight = getContext().getResources().getDimensionPixelSize(
            R.dimen.settings_product_item_height);
    int height = rowHeight * mProducts.size()
            + MetricHelper.dpToPixel(getContext(), 10);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, height);
    mListView.setLayoutParams(layoutParams);
}

public List<ProductVisibility> getProductsVisibility() {
    return mAdapter.getData();
}

public void setEditOrderMode(boolean editOrderMode) {
    mAdapter.setShowDrag(editOrderMode);
    mListView.setDropListener(editOrderMode ? mDropListener : null);
    mAdapter.notifyDataSetChanged();
}

public boolean canStillDeselectProduct() {
    if (!mShouldHaveAtLeastOneSelected)
        return true;

    int nb = 0;
    for (ProductVisibility pv : mAdapter.getData()) {
        nb += pv.isVisible() ? 1 : 0;
    }
    return nb > 1;
}

public boolean hasChanged() {
    return mHasChanged;
}

private class ProductAdapter extends BaseAdapter {
    private boolean mShowDrag;
    private List<ProductVisibility> data;


    public ProductAdapter(List<ProductVisibility> data) {
        this.data = data;
    }

    public void moveData(int from, int to) {
        ProductVisibility ProductVisibilityFrom = this.data.get(from);
        data.remove(ProductVisibilityFrom);
        data.add(to, ProductVisibilityFrom);
    }

    public List<ProductVisibility> getData() {
        return data;
    }

    @Override
    public Object getItem(int position) {

        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public int getCount() {

        return data.size();
    }

    public void setShowDrag(boolean flag) {
        mShowDrag = flag;
    }

    public boolean isLast(int position) {
        return position == getCount() - 1;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //re-use of convertView removed because of problem when reuse of listeners
        convertView = View.inflate(getContext(),R.layout.settings_product_order_list_item, null);
        ProductVisibility productVisibility = (ProductVisibility) getItem(position);
        IProduct product = productVisibility.getProduct();
        TextView mTypeLabel = (TextView)convertView.findViewById(R.id.typeLabel);
        TextView mNameLabel =  (TextView)convertView.findViewById(R.id.nameLabel);
        TextView mNumberLabel =  (TextView)convertView.findViewById(R.id.numberLabel);
        Switch mOnOffSwitch =(Switch) convertView.findViewById(R.id.toggle);
        ImageView mDrag = (ImageView)convertView.findViewById(R.id.drag);
        View mSeparator = convertView.findViewById(R.id.separator);
        mTypeLabel.setText(product.getDescription());
        mNameLabel.setText(product.getNameHolder());
        mNumberLabel.setText(product.getProductNumber());
        mOnOffSwitch.setChecked(productVisibility.isVisible());
        mOnOffSwitch.setVisibility(mShowDrag ? View.GONE : View.VISIBLE);
        mDrag.setVisibility(mShowDrag ? View.VISIBLE : View.GONE);
        mSeparator.setVisibility(!isLast(position) ? View.VISIBLE: View.GONE);
        //Can't resuse this listener via inflation
        mOnOffSwitch.setOnCheckedChangeListener(new SwitchOnCheckListener(productVisibility));
        TypefaceHelper.applyTypeface(TypefaceName.ROBOTO_REGULAR, mOnOffSwitch);
        TypefaceHelper.applyTypeface(TypefaceName.ROBOTO_REGULAR, mTypeLabel);
        TypefaceHelper.applyTypeface(TypefaceName.ROBOTO_REGULAR, mNameLabel);
        TypefaceHelper.applyTypeface(TypefaceName.ROBOTO_REGULAR, mNumberLabel);
        return convertView;
    }


    private void showAlertLastProductUnchecked() {
        AlertDialogHelper
                .getBuilder(getContext())
                .setTitle("")
                .setMessage(R.string.a24_error_minimum_account_message)
                .setPositiveButton(
                        R.string.a24_error_minimum_account_button_label,
                        null).show();
    }

    private class SwitchOnCheckListener implements  OnCheckedChangeListener{
        private ProductVisibility productVisibility;
        public SwitchOnCheckListener(ProductVisibility productVisibility){
            this.productVisibility=productVisibility;
        }
        @Override
        public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
            if (isChecked) {
                productVisibility.setVisible(true);
                mHasChanged = true;
            } else {
                if (canStillDeselectProduct()) {
                    productVisibility.setVisible(false);
                    mHasChanged = true;
                } else {
                    buttonView.setChecked(true);
                    showAlertLastProductUnchecked();
                }
            }
        }
    }


}

}

and here is our xml describing a single list item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" xmlns:test="http://schemas.android.com/apk/res/be.test.android">

<RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="@dimen/settings_product_item_height" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@+id/actionContainer"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/typeLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lines="1"
            android:shadowColor="#fff"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="BLUE REKENING"
            android:textAllCaps="true"
            android:textColor="#78736E" />

        <TextView
            android:id="@+id/nameLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lines="1"
            android:shadowColor="#fff"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="Sterck &amp; co bvba"
            android:textColor="#51626F" />

        <TextView
            android:id="@+id/numberLabel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:lines="1"
            android:shadowColor="#fff"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="BE1234567890"
            android:textColor="#78736E" />
    </LinearLayout>

   <RelativeLayout
        android:id="@+id/actionContainer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true" >

          <be.test.android.widget.Switch
              style="@style/Widget.Button.Switch"
            android:id="@+id/toggle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:checked="true" />

        <ImageView
            android:id="@+id/drag"
            android:layout_width="wrap_content"
            android:layout_height="60dp"
            android:src="@drawable/drag_handle" />

    </RelativeLayout>
</RelativeLayout>
<View android:id="@+id/separator"
     android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#CFCFCC" />

axelsegers avatar Oct 21 '12 09:10 axelsegers

We fixed the problem by specifying a fixed height for the separator item

<View android:id="@+id/separator" android:layout_width="match_parent" android:layout_height="3px" android:background="#CFCFCC" />

It seems that the total height of all items is not calculated correctly when specifying this in dp

axelsegers avatar Oct 24 '12 14:10 axelsegers

Okay, thanks. Glad that worked. I will try to reproduce the issue on my end, see what went wrong.

bauerca avatar Oct 24 '12 23:10 bauerca

Well it seems not to be solved. The total height of all items is calculated incorrectly. this results in a list which does not show all items .. can you please take a look at it.

axelsegers avatar Oct 25 '12 12:10 axelsegers

Drat. Okay. Will be a few days... swamped.

bauerca avatar Oct 26 '12 06:10 bauerca