Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add dots to TextView like in the receipt

I want to implement something like a product list in the receipt:
Beer ......................................... 20
Milk .......................................... 10
Cookies with jam ..................... 15
Smartphone 10GB 3GHz
1GB RAM NFC 10MPx
camera .................................. 400

Description: Check info (Beer, Milk) I think it shoud be a TextView, which I need to fill with dots.
Money (20, 10) is another TextView which shoud be aligned to the right of ViewGroup.

Any ideas how to do this? Maybe I need inherited from TextView and override onDraw() or something?
Many thank for advices!!!

like image 851
Sergey Avatar asked Feb 17 '23 02:02

Sergey


2 Answers

You should create THREE TextViews for each row, layed out one next to another:

  1. TextView With product name (e.g. 'beer')
  2. TextView with dots
  3. TextView with number (e.g. '20')

Then put one product in one row. The Row should be relative layout where:

  • TextView no. 1 is aligned to left edge, with width set to wrap content
  • TextView no. 3 is aligneg to right edge, with width set to wrap content
  • TextView no. 2 is toLeftOf TV no. 3 and toRightOf TV no.1 and it should be filled with big amount of dots in XML file. this will never be changed.

This will work, since the TV no.2 will have width that will shrink and will always be fitted between product name and the price. believe me :)

like image 183
Jacek Milewski Avatar answered Feb 22 '23 01:02

Jacek Milewski


I have the solution. Maybe it will help someone.

  1. File check_info_item.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="horizontal">
    <RelativeLayout android:layout_width="match_parent"
              android:layout_height="wrap_content">
    
    <TextView android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:id="@+id/txt_fake_value"
              android:textSize="18dp"
              android:textColor="@android:color/transparent"
              android:layout_alignParentRight="true"/>
    <example.com.CheckInfoTextView android:layout_height="wrap_content"
              android:layout_width="match_parent"
              android:id="@+id/txt_fake_info"
              android:textSize="18dp"
              android:textColor="@android:color/transparent"
              android:layout_alignParentLeft="true"
              android:layout_toLeftOf="@id/txt_fake_value"/>
    <TextView android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:id="@+id/txt_check_info_value"
              android:text=""
              android:textSize="18dp"
              android:textColor="#000"
              android:layout_alignParentRight="true"
              android:layout_alignBottom="@id/txt_fake_info"/>
    <example.com.CheckInfoTextView
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:textSize="18dp"
            android:textColor="#000"
            android:id="@+id/txt_check_info"
            android:text=""
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@id/txt_check_info_value"/>
    </RelativeLayout>
    </LinearLayout>
    
  2. Code to fill the info fields (in the Activity):

        View row = getLayoutInflater().inflate(R.layout.check_info_item, null);
        //Fake fields needed to align base fields in the xml file
        TextView txtFakeValue = (TextView) row.findViewById(R.id.txt_fake_value);
        txtFakeValue.setText(String.valueOf(pair.second));
    
        TextView txtFake = (TextView) row.findViewById(R.id.txt_fake_info);
        txtFake.setText(pair.first);
    
        TextView txtValue = (TextView) row.findViewById(R.id.txt_check_info_value);
        txtValue.setText(String.valueOf(pair.second));
    
        TextView txtTitle = (TextView) row.findViewById(R.id.txt_check_info);
        txtTitle.setText(pair.first);
    
  3. And the CheckInfoTextView:

    public class CheckInfoTextView extends TextView {
    
    
        public CheckInfoTextView(Context context) {
            super(context);
        }
    
        public CheckInfoTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CheckInfoTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            super.onWindowFocusChanged(hasWindowFocus);
            if(!hasWindowFocus) return;
    
            int requiredDots = getRequiredDotsNumber();
            if(requiredDots == 0) {
                String text = getText().toString();
                StringBuilder result = new StringBuilder();
                result.append(text.substring(0, text.lastIndexOf(' ')));
                result.append("\n");
                result.append(text.substring(text.lastIndexOf(' ') + 1));
                setText(result.toString());
    
                requiredDots = getRequiredDotsNumber();
            }
            String dots = "";
            for (int i = 0; i < requiredDots; ++i) {
                dots += " .";
            }
            setText(getText() + dots);
        }
    
        private int getRequiredDotsNumber() {
            final int width = getWidth();
            final int lastLineWidth = (int) getLayout().getLineWidth(getLineCount() - 1);
            final int availableWidthForDots = width - lastLineWidth;
            final int widthOfOneDot = getWidthOfOneDot();
            final int widthOfTwoDotsWithSpace = getWidthOfTwoDotsWithSpace();
            final int widthOfSpace = widthOfTwoDotsWithSpace - (widthOfOneDot * 2);
            final int widthOfDotWithSpace = widthOfSpace + widthOfOneDot;
            int numberOfDots = availableWidthForDots / widthOfDotWithSpace;
            return numberOfDots;
        }
    
        private int getWidthOfTwoDotsWithSpace() {
           return getStringWidth(". .");
        }
    
        private int getWidthOfOneDot() {
           return getStringWidth(".");
        }
    
        private int getStringWidth(String text) {
            Rect dotBounds = new Rect();
            getPaint().getTextBounds(text,0,text.length(),dotBounds);
            return dotBounds.width();
        }
    }
    
like image 42
Sergey Avatar answered Feb 22 '23 00:02

Sergey