সমুজ্জ্বল রিলেটিভ লেআউটে তেঁতুলিতে


86

RelativeLayoutঅ্যান্ড্রয়েডের মতো করে কিছু কার্যকর করার কোনও উপায় আছে কি ?

বিশেষ করে আমি কিছু খুঁজছি অনুরূপ centerInParent, layout_below:<layout_id>, layout_above:<layout_id>, এবংalignParentLeft

সম্পর্কিত সম্পর্কিত লেআউট সম্পর্কে আরও রেফারেন্সের জন্য: https://developer.android.com/references/android/widget/RelativeLayout.LayoutParams.html

সম্পাদনা: এখানে নির্ভর একটি বিন্যাসের উদাহরণ RelativeLayout

স্ক্রিনশট

সুতরাং উপরের চিত্রটিতে, শীর্ষে, "তোফুর গানগুলি" পাঠ্যটি centerInParentএকটি এর অভ্যন্তরে প্রান্তিক করা হয়েছে RelativeLayout। যেখানে অন্য 2 টি alignParentLeftএবংalignParentRight

প্রতিটি কক্ষে, যেখানে ফায়ার আইকন থাকে সেখানে নীচের অংশে পছন্দগুলির সংখ্যা শিখা আইকনটির কেন্দ্রস্থলে সংযুক্ত থাকে। এছাড়াও, প্রতিটি ঘরের উপরের এবং নীচের শিরোনামটি যথাক্রমে চিত্র অবতারের ডানদিকে এবং নীচে এবং নীচে একত্রিত হয়।

উত্তর:


214

পাখির লেআউট সাধারণত একটি গাছ ব্যবহার করে নির্মিত হয় Column, Rowএবং Stackউইজেট। এই উইজেট কন্সট্রাকটর যুক্তি হল যে কিভাবে শিশুরা তাদের পিতা বা মাতা আপেক্ষিক পরিপূর্ণ জন্য নিয়ম উল্লেখ নিতে, এবং আপনি তাদের মধ্যে মোড়কে পৃথক শিশুদের বিন্যাস প্রভাবিত করতে পারে Expanded, Flexible, Positioned, Align, অথবা Centerউইজেট।

এটি ব্যবহার করে জটিল বিন্যাসগুলি তৈরি করাও সম্ভব CustomMultiChildLayout। এভাবেই Scaffoldঅভ্যন্তরীণভাবে প্রয়োগ করা হয় এবং এটি কোনও অ্যাপে কীভাবে ব্যবহার করা যায় তার একটি উদাহরণ শ্রাইন ডেমোতে উপস্থিত হয় । এছাড়াও আপনি ব্যবহার করতে পারেন LayoutBuilderবা CustomPaint, বা ডাউন একটি স্তর যান এবং প্রসারিত RenderObjectহিসাবে দেখানো খাতের উদাহরণ । আপনার লেআউটটিকে ম্যানুয়ালি এইভাবে করা আরও বেশি কাজ এবং কোণার ক্ষেত্রে ত্রুটির জন্য আরও সম্ভাবনা তৈরি করে, তাই যদি আপনি পারেন তবে আমি উচ্চ-স্তরের লেআউট আদিমকে সাথে নিয়ে যাওয়ার চেষ্টা করব।

আপনার নির্দিষ্ট প্রশ্নের উত্তর দিতে:

  • আপনার অ্যাপ্লিকেশন বারের উপাদানগুলিকে স্থাপন করতে যুক্তি leadingএবং trailingযুক্তি ব্যবহার করুন AppBar। আপনি যদি একটি ব্যবহার করতে চান তাহলে Rowএর পরিবর্তে, ব্যবহার mainAxisAlignmentএর MainAxisAlignment.spaceBetween
  • একটি ব্যবহার করুন Rowএকটি সঙ্গে crossAxisAlignmentএর CrossAxisAlignment.centerআগুন আইকন এবং সংখ্যা নীচে জায়গায় স্থাপনের জন্য।
  • আপনার শীর্ষ এবং নীচের শিরোনামের অবস্থানের জন্য একটি Columnসহ একটি ব্যবহার করুন । ( তালিকার টাইলগুলি ছড়িয়ে দেওয়ার জন্য আপনার ব্যবহার বিবেচনা করা উচিত , তবে আপনি যদি এটি করেন তবে সঠিক অবস্থানের উপর নিয়ন্ত্রণ হারাবেন))mainAxisAlignmentMainAxisAlignment.spaceBetweenListTile

এখানে একটি কোড স্নিপেট যা আপনার সরবরাহিত নকশাকে কার্যকর করে। এই উদাহরণে আমি IntrinsicHeightগানের টাইলগুলির উচ্চতা নির্ধারণ করতে একটি ব্যবহার করেছি , তবে আপনি নির্দিষ্ট উচ্চতায় কঠোরভাবে কোডিং করে পারফরম্যান্সটি উন্নত করতে পারেন।

স্ক্রিনশট

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        brightness: Brightness.dark,
        primaryColorBrightness: Brightness.dark,
      ),
      home: new HomeScreen(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class Song extends StatelessWidget {
  const Song({ this.title, this.author, this.likes });

  final String title;
  final String author;
  final int likes;

  @override
  Widget build(BuildContext context) {
    TextTheme textTheme = Theme
      .of(context)
      .textTheme;
    return new Container(
      margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0),
      padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
      decoration: new BoxDecoration(
        color: Colors.grey.shade200.withOpacity(0.3),
        borderRadius: new BorderRadius.circular(5.0),
      ),
      child: new IntrinsicHeight(
        child: new Row(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            new Container(
              margin: const EdgeInsets.only(top: 4.0, bottom: 4.0, right: 10.0),
              child: new CircleAvatar(
                backgroundImage: new NetworkImage(
                  'http://thecatapi.com/api/images/get?format=src'
                    '&size=small&type=jpg#${title.hashCode}'
                ),
                radius: 20.0,
              ),
            ),
            new Expanded(
              child: new Container(
                child: new Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    new Text(title, style: textTheme.subhead),
                    new Text(author, style: textTheme.caption),
                  ],
                ),
              ),
            ),
            new Container(
              margin: new EdgeInsets.symmetric(horizontal: 5.0),
              child: new InkWell(
                child: new Icon(Icons.play_arrow, size: 40.0),
                onTap: () {
                  // TODO(implement)
                },
              ),
            ),
            new Container(
              margin: new EdgeInsets.symmetric(horizontal: 5.0),
              child: new InkWell(
                child: new Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    new Icon(Icons.favorite, size: 25.0),
                    new Text('${likes ?? ''}'),
                  ],
                ),
                onTap: () {
                  // TODO(implement)
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Feed extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new ListView(
      children: [
        new Song(title: 'Trapadelic lobo', author: 'lillobobeats', likes: 4),
        new Song(title: 'Different', author: 'younglowkey', likes: 23),
        new Song(title: 'Future', author: 'younglowkey', likes: 2),
        new Song(title: 'ASAP', author: 'tha_producer808', likes: 13),
        new Song(title: '🌲🌲🌲', author: 'TraphousePeyton'),
        new Song(title: 'Something sweet...', author: '6ryan'),
        new Song(title: 'Sharpie', author: 'Fergie_6'),
      ],
    );
  }
}

class CustomTabBar extends AnimatedWidget implements PreferredSizeWidget {
  CustomTabBar({ this.pageController, this.pageNames })
    : super(listenable: pageController);

  final PageController pageController;
  final List<String> pageNames;

  @override
  final Size preferredSize = new Size(0.0, 40.0);

  @override
  Widget build(BuildContext context) {
    TextTheme textTheme = Theme
      .of(context)
      .textTheme;
    return new Container(
      height: 40.0,
      margin: const EdgeInsets.all(10.0),
      padding: const EdgeInsets.symmetric(horizontal: 20.0),
      decoration: new BoxDecoration(
        color: Colors.grey.shade800.withOpacity(0.5),
        borderRadius: new BorderRadius.circular(20.0),
      ),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: new List.generate(pageNames.length, (int index) {
          return new InkWell(
            child: new Text(
              pageNames[index],
              style: textTheme.subhead.copyWith(
                color: Colors.white.withOpacity(
                  index == pageController.page ? 1.0 : 0.2,
                ),
              )
            ),
            onTap: () {
              pageController.animateToPage(
                index,
                curve: Curves.easeOut,
                duration: const Duration(milliseconds: 300),
              );
            }
          );
        })
          .toList(),
      ),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  PageController _pageController = new PageController(initialPage: 2);

  @override
  build(BuildContext context) {
    final Map<String, Widget> pages = <String, Widget>{
      'My Music': new Center(
        child: new Text('My Music not implemented'),
      ),
      'Shared': new Center(
        child: new Text('Shared not implemented'),
      ),
      'Feed': new Feed(),
    };
    TextTheme textTheme = Theme
      .of(context)
      .textTheme;
    return new Stack(
      children: [
        new Container(
          decoration: new BoxDecoration(
            gradient: new LinearGradient(
              begin: FractionalOffset.topCenter,
              end: FractionalOffset.bottomCenter,
              colors: [
                const Color.fromARGB(255, 253, 72, 72),
                const Color.fromARGB(255, 87, 97, 249),
              ],
              stops: [0.0, 1.0],
            )
          ),
          child: new Align(
            alignment: FractionalOffset.bottomCenter,
            child: new Container(
              padding: const EdgeInsets.all(10.0),
              child: new Text(
                'T I Z E',
                style: textTheme.headline.copyWith(
                  color: Colors.grey.shade800.withOpacity(0.8),
                  fontWeight: FontWeight.bold,
                ),
              ),
            )
          )
        ),
        new Scaffold(
          backgroundColor: const Color(0x00000000),
          appBar: new AppBar(
            backgroundColor: const Color(0x00000000),
            elevation: 0.0,
            leading: new Center(
              child: new ClipOval(
                child: new Image.network(
                  'http://i.imgur.com/TtNPTe0.jpg',
                ),
              ),
            ),
            actions: [
              new IconButton(
                icon: new Icon(Icons.add),
                onPressed: () {
                  // TODO: implement
                },
              ),
            ],
            title: const Text('tofu\'s songs'),
            bottom: new CustomTabBar(
              pageController: _pageController,
              pageNames: pages.keys.toList(),
            ),
          ),
          body: new PageView(
            controller: _pageController,
            children: pages.values.toList(),
          ),
        ),
      ],
    );
  }
}

ফাইনাল নোট: এই উদাহরণে, আমি একজন নিয়মিত ব্যবহৃত AppBar, কিন্তু আপনি একটি ব্যবহার করতে পারে CustomScrollViewএকটি পিন করা সঙ্গে SliverAppBarথাকে যে, কোন elevation0.0 এর। এটি আপনার অ্যাপ্লিকেশন বারের পিছনে স্ক্রোল করার সাথে সাথে সামগ্রীটি দৃশ্যমান করে তুলবে। এটির সাথে সুন্দরভাবে খেলতে পারাটা মুশকিল PageView, কারণ এটি একটি নির্দিষ্ট আকারের ক্ষেত্রের মধ্যে নিজেকে বিভক্ত করার প্রত্যাশা করে।


ব্যবহারকারী দ্বারা ফন্টের আকার পরিবর্তন করা যেতে পারে এবং বিন্যাসটি সহজেই ভেঙে যেতে পারে বলে আমি অন্তর্নিহিত উচ্চতা বাদ দেওয়ার প্রস্তাব দিই না।
লুকাসজ সিয়াস্টকো

25

আপনি এটি ব্যবহার করতে পারেন Stackএবং তার সন্তানদেরও Positionedবা হিসাবে থাকতে পারেন Align

উদাহরণ # 1 (ব্যবহারPositionedকরেStack)

Stack(
  children: <Widget>[
    Positioned(left: 0.0, child: Text("Top\nleft")),
    Positioned(bottom: 0.0, child: Text("Bottom\nleft")),
    Positioned(top: 0.0, right: 0.0, child: Text("Top\nright")),
    Positioned(bottom: 0.0, right: 0.0, child: Text("Bottom\nright")),
    Positioned(bottom: 0.0, right: 0.0, child: Text("Bottom\nright")),
    Positioned(left: width / 2, top: height / 2, child: Text("Center")),
    Positioned(top: height / 2, child: Text("Center\nleft")),
    Positioned(top: height / 2, right: 0.0, child: Text("Center\nright")),
    Positioned(left: width / 2, child: Text("Center\ntop")),
    Positioned(left: width / 2, bottom: 0.0, child: Text("Center\nbottom")),
  ],
)

উদাহরণ # 2 (ব্যবহারAlignকরেStack)

Stack(
  children: <Widget>[
    Align(alignment: Alignment.center, child: Text("Center"),),
    Align(alignment: Alignment.topRight, child: Text("Top\nRight"),),
    Align(alignment: Alignment.centerRight, child: Text("Center\nRight"),),
    Align(alignment: Alignment.bottomRight, child: Text("Bottom\nRight"),),
    Align(alignment: Alignment.topLeft, child: Text("Top\nLeft"),),
    Align(alignment: Alignment.centerLeft, child: Text("Center\nLeft"),),
    Align(alignment: Alignment.bottomLeft, child: Text("Bottom\nLeft"),),
    Align(alignment: Alignment.topCenter, child: Text("Top\nCenter"),),
    Align(alignment: Alignment.bottomCenter, child: Text("Bottom\nCenter"),),
    Align(alignment: Alignment(0.0, 0.5), child: Text("Custom\nPostition", style: TextStyle(color: Colors.red, fontSize: 20.0, fontWeight: FontWeight.w800),),),
  ],
);

স্ক্রিনশট:

এখানে চিত্র বর্ণনা লিখুন


4
সত্যই সহায়ক, আমি মনে করি অ্যান্ড্রয়েড থেকে আসা বেশিরভাগ বিকাশকারীরা কনস্ট্রেন্ট লেআউটের মতো লেআউট খুঁজছেন। এলোমেলো কিছু আছে কি?
ব্যবহারকারী 3833732

4
@ ইউজার ৩৩৩৩ut৩২ আপনি খুব বেশি কিছু করতে পারবেন ফ্লার্ট ইনবিল্ট উইজেট ব্যবহার করে achieve আপনার যদি কোনও লেআউট থাকে এবং আপনি ভাবেন যে আপনি এলোপাতাড়ি ব্যবহার করে এটি প্রয়োগ করতে সক্ষম নন, এটি একটি প্রশ্ন হিসাবে পোস্ট করুন এবং আমাকে বার্তা দিন, আমি এটির উত্তর দেওয়ার চেষ্টা করব।
কক্সঅনরোড

3

এটির মতো কাজ করতে কীভাবে Stackপাশাপাশি কীভাবে Positionedব্যবহার করা যায় তা দেখানোর জন্য এখানে আরও একটি উদাহরণ রয়েছে RelativeLayout

এখানে চিত্র বর্ণনা লিখুন

double _containerHeight = 120, _imageHeight = 80, _iconTop = 44, _iconLeft = 12, _marginLeft = 110;

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    body: Stack(
      children: <Widget>[
        Positioned(
          left: 0,
          right: 0,
          height: _containerHeight,
          child: Container(color: Colors.blue),
        ),
        Positioned(
          left: _iconLeft,
          top: _iconTop,
          child: Icon(Icons.settings, color: Colors.white),
        ),
        Positioned(
          right: _iconLeft,
          top: _iconTop,
          child: Icon(Icons.bubble_chart, color: Colors.white),
        ),
        Positioned(
          left: _iconLeft,
          top: _containerHeight - _imageHeight / 2,
          child: ClipOval(child: Image.asset("assets/images/profile.jpg", fit: BoxFit.cover, height: _imageHeight, width: _imageHeight)),
        ),
        Positioned(
          left: _marginLeft,
          top: _containerHeight - (_imageHeight / 2.5),
          child: Text("CopsOnRoad", style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500, fontSize: 18)),
        ),
        Positioned.fill(
          left: _marginLeft,
          top: _containerHeight + (_imageHeight / 4),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Column(
                children: <Widget>[
                  Text("2", style: TextStyle(fontWeight: FontWeight.bold)),
                  Text("Gold", style: TextStyle(color: Colors.grey)),
                ],
              ),
              Column(
                children: <Widget>[
                  Text("22", style: TextStyle(fontWeight: FontWeight.bold)),
                  Text("Silver", style: TextStyle(color: Colors.grey)),
                ],
              ),
              Column(
                children: <Widget>[
                  Text("28", style: TextStyle(fontWeight: FontWeight.bold)),
                  Text("Bronze", style: TextStyle(color: Colors.grey)),
                ],
              ),
              Container(),
            ],
          ),
        ),
      ],
    ),
  );
}

2

অ্যান্ড্রয়েডের মতো RelativeLayout(এবং বাস্তবে আরও শক্তিশালী) হ'ল প্যাকেজটির AlignPositionedউইজেট align_positioned:

https://pub.dev/packages/align_positioned

এর ডক্স থেকে:

যখন আপনার কাঙ্ক্ষিত বিন্যাসটি কলাম এবং সারিগুলির জন্য খুব জটিল অনুভূত হয়, তখন AlignPiseded একটি বাস্তব জীবন রক্ষাকারী is ঝাঁকুনি খুব কম্পোজেবল, যা ভাল, তবে কখনও কখনও এটি কিছু সাধারণ বিন্যাসের প্রয়োজনে কিছু সরল উইজেটের অনুবাদ করতে অকারণে জটিল।

অ্যালাইনপজিশনেড কনটেইনার এবং শিশু উভয়ের সাথেই তার সন্তানের সাথে সংযুক্তি, অবস্থান, আকার, ঘোরানো এবং রূপান্তর করে। অন্য কথায়, এটি আপনাকে সহজে এবং সরাসরি সংজ্ঞা দিতে দেয় যে কোনও উইজেট অন্যের সাথে কীভাবে প্রদর্শিত হবে appear

উদাহরণস্বরূপ, আপনি এটিকে ধারকটির উপরের-বাম কোণে 15 পিক্সেলে তার সন্তানের উপরের বামে অবস্থিত রাখতে বলতে পারেন, এবং এটি সন্তানের উচ্চতার দুই তৃতীয়াংশ নীচে প্লাস 10 পিক্সেলে সরান এবং তারপরে 15 ডিগ্রি ঘোরান। আপনি কি জানেন কীভাবে বেসিক ফ্লুটার উইজেটগুলি রচনা করে এটি করা শুরু করবেন? হতে পারে, তবে অ্যালাইনপজিশনে এটি অনেক সহজ এবং এটি একটি একক উইজেট নেয়।

তবে, প্রশ্নের নির্দিষ্ট উদাহরণটি বেশ সহজ, আমি যাইহোক Row, কেবল এস, Columnএস ব্যবহার করব। দ্রষ্টব্য: আমি এই প্যাকেজটির লেখক।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.