skip to Main Content

I have an "infinite vertical scroll" with unconstrained height of the card. The only constraint is set for the image and all other elements shrink/expand to the remaining size. Text lines can expand max to 3 lines and title can expand max to 2 lines. So, the height of the text part might vary heavily: from 2 lines (1 line title + 1 line description) to 5 lines (2 lines title + 3 lines description).

Is there any possibility to align the row with the price and "Grab" button to the bottom of the card?

I’ve already tried all possibly align / stack / … solutions with no luck unless I set a constant height of the card which I don’t want to do.

Please, check image to see what I’m trying to achieve.

enter image description here

Update: adding some code that I have currently as asked (removed irrelevant code like styling)

Infinite scroll definition:

      ...
      builderDelegate: PagedChildBuilderDelegate<Deal>(
        itemBuilder: (context, deal, index) => Container(
            padding: EdgeInsets.all(8),
            child: DealRow(deal: deal)
        ),
    ...

DealRow:

return GestureDetector(
  ...
  child: Container(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // item image
            Container(
              width: MediaQuery.sizeOf(context).width * layoutConstants.dealImageWidthFraction,
              height: MediaQuery.sizeOf(context).width * layoutConstants.dealImageWidthFraction,
              alignment: Alignment.center,
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(16),
                image: DecorationImage(
                    // We keep Box.fit cover in inverted colors so the white image background on dark container background looks homogenous
                    image: NetworkImage(deal.imageUrl), fit: BoxFit.contain,
                ),
    ...
            ),
    // item details
            Expanded(child: Container(
              padding: EdgeInsets.only(left: 8),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    deal.title,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 2,
                  ),
                  SizedBox(height: 8),
                  Text(
                    deal.description,
                    maxLines: layoutConstants.maxDescriptionLines,
                    overflow: TextOverflow.ellipsis,
                  ),
                  Stack(
                    children: [
                      Container(height: 50, alignment: Alignment.centerLeft, child:
                        PriceRow(deal: deal),
                      ),
                      Container(alignment: Alignment.centerRight, child:
                        TextButton(
                          child: Text(layoutConstants.size == LayoutSize.large ? "Grab a Deal" : "Grab", style: TextStyle(color: AppColor.primarySoft),),
...
)

PriceRow:

return Row(
      crossAxisAlignment: CrossAxisAlignment.end,
      children: [
        if (deal.originalPrice != null && deal.originalPrice! > 0) Container(
            padding: const EdgeInsets.only(right: 4),
            child: Text(
                formatCurrency.format(deal.originalPrice),
            )
        ),
        Container(
          // margin: EdgeInsets.only(top: 2, bottom: 8),
          child: Text(
            formatCurrency.format(deal.resultingPrice),
          ),
        ),
      ],
    );

2

Answers


  1. I assume your title description and price part is wrapped with Column. Additionally, wrap title and desc with Column. Add parent Column widget MainAxisAlignmnet.spaceBetween.

    Final structure should be like this:

    Column (
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children:[
        Column(
          children: [
            Title(),
            Description(),
          ],
           
        ),
        PriceWidget(),
      ] 
    )
    

    If you share a code snippet, i can help better

    ***updated
    After you share code, adding height of the image to the Expanded Container, and also adding Spacer between, desc and Stack will solve the issue.

    Expanded(child: Container(
    height: MediaQuery.sizeOf(context).width * layoutConstants.dealImageWidthFraction,
                          padding: EdgeInsets.only(left: 8),
    

    …..

     Text(
     deal.description,
     maxLines: layoutConstants.maxDescriptionLines,
     overflow: TextOverflow.ellipsis,
    ),
    const Spacer(),
    Stack(
       children: [
         Container(height: 50, alignment: Alignment.centerLeft, child:
                            PriceRow(deal: deal),
                          ),
    
    Login or Signup to reply.
  2. Try the hierarchy below for desired list view row item structure. Hope it helps

              Container(
                    margin: EdgeInsets.all(5),
                    color: Colors.lightGreenAccent,
                    child: Row(
                      children: [
                        Icon(Icons.abc, size: 50),
                        Expanded(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Text('title'),
                                  Text('subtitle'),
                                ],
                              ),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Row(
                                    children: [Text('price1'), Text('price2')],
                                  ),
                                  Text('Grab'),
                                ],
                              )
                            ],
                          ),
                        )
                      ],
                    ));
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search