RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-291298

fantik's questions

Martin Hope
fantik
Asked: 2020-02-22 01:57:35 +0000 UTC

如何从本地存储中获取令牌?

  • 0

授权后,将颁发用户令牌,并保存该令牌。如果它在本地存储中可用并且在关闭应用程序后,则不需要进一步授权。这里一切正常,但是有一个 CreatePage 类,它再次需要一个令牌,我在从本地存储中获取它时遇到问题(尽管如果我直接将它插入代码中,它可以工作),服务器返回错误:“401 Unauthorized ”。flutter_secure_storage 库用于存储令牌。

AuthPage.dart

import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:localstorage/localstorage.dart';
import 'package:http/http.dart' as http;
import 'package:digitalpendal/main.dart';
import 'package:digitalpendal/screens/Authentication/RegistrationPage.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class AuthPage extends StatefulWidget {
  @override
  _AuthPageState createState() => _AuthPageState();
}

class _AuthPageState extends State<AuthPage> {
  String _email;
  String _password;
  final LocalStorage storage = new LocalStorage('some_key');
  final _sizeTextBlack = const TextStyle(fontSize: 20.0, color: Colors.black);
  final _sizeTextWhite = const TextStyle(fontSize: 20.0, color: Colors.white);
  final formKey = new GlobalKey<FormState>();
  BuildContext _context;


  @override
  Widget build(BuildContext context) {
    _context = context;
    return new MaterialApp(
      debugShowCheckedModeBanner: false,
      home: new Scaffold(
        body: new Center(
          child: new Form(
              key: formKey,
              child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  new Container(
                    child: new TextFormField(
                      decoration: new InputDecoration(
                        labelText: "Логин",
                        fillColor: Colors.white,
                        border: new OutlineInputBorder(
                          borderRadius: new BorderRadius.circular(25.0),
                          borderSide: new BorderSide(),
                        ),
                        //fillColor: Colors.green
                      ),
                      keyboardType: TextInputType.emailAddress,
                      maxLines: 1,
                      style: _sizeTextBlack,
                      onSaved: (val) => _email = val,
                      validator: (val) =>
                          !val.contains("@") ? 'Not a valid email.' : null,
                    ),
                    width: 340.0,
                    height: 50,
                    padding: new EdgeInsets.only(top: 10.0),
                  ),
                  new Padding(padding: new EdgeInsets.only(top: 25.0)),
                  new Container(
                    child: new TextFormField(
                      decoration: new InputDecoration(
                        labelText: "Пароль",
                        fillColor: Colors.white,
                        border: new OutlineInputBorder(
                          borderRadius: new BorderRadius.circular(25.0),
                          borderSide: new BorderSide(),
                        ),
                        //fillColor: Colors.green
                      ),
                      obscureText: true,
                      maxLines: 1,
                      validator: (val) =>
                          val.length < 2 ? 'Password too short.' : null,
                      onSaved: (val) => _password = val,
                      style: _sizeTextBlack,
                    ),
                    width: 340.0,
                    height: 50,
                    padding: new EdgeInsets.only(top: 10.0),
                  ),
                  new Padding(
                    padding: new EdgeInsets.only(top: 25.0),
                    child: new MaterialButton(
                      onPressed: submit,
                      color: Theme.of(context).accentColor,
                      height: 50.0,
                      minWidth: 150.0,
                      child: new Text(
                        "Войти",
                        style: _sizeTextWhite,
                      ),
                    ),
                  ),
                  new Padding(
                    padding: new EdgeInsets.only(top: 25.0),
                    child: new MaterialButton(
                      onPressed: submitForm,
                      color: Colors.white,
                      height: 50.0,
                      minWidth: 150.0,
                      child: new Text(
                        "Зарегистрироваться",
                        style: _sizeTextBlack,
                      ),
                    ),
                  ),
                ],
              )),
        ),
      ),
    );
  }

  void submit() {
    final form = formKey.currentState;
    if (form.validate()) {
      form.save();
      signIn();
    }
  }

  void login() {
    final form = formKey.currentState;
    if (form.validate()) {
      form.save();
      submitForm();
    }
  }

  signIn() async {
    final storage = new FlutterSecureStorage();
    Map data = {
      'email': _email,
      'password': _password
    };
    var jsonResponse = null;
    var response = await http.post("http://192.168.0.104:8000/api/v1/auth_token/token/login/", body: data);
    if(response.statusCode == 200) {
      jsonResponse = json.decode(response.body);
      if(jsonResponse != null) {
        setState(() {

        });
        await storage.write(key: "auth_token", value: 'auth_token');
        Navigator.of(_context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => MyBottomNavigationBar()), (Route<dynamic> route) => false);
      }
    }
    else {
      setState(() {

      });
      print(response.body);
    }
  }

  void hideKeyboard() {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }
  void fucktheAuth(){
    hideKeyboard();
    Navigator.push(_context,
        new MaterialPageRoute(builder: (context) => new MyBottomNavigationBar()));
  }



  void submitForm() {
    hideKeyboard();
    Navigator.push(_context,
        new MaterialPageRoute(builder: (context) => new RegistrationPage()));
  }
}

主要.dart

import 'package:digitalpendal/TaskPage.dart';
import 'package:digitalpendal/screens/Authentication/AuthPage.dart';
import 'package:digitalpendal/screens/Create_page/CreatePage.dart';
import 'package:digitalpendal/screens/Profile_Page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(

      theme: ThemeData(primaryColor: Colors.blue.shade900),
      debugShowCheckedModeBanner: false,
      home: MyBottomNavigationBar(),
    );
  }
}

class MyBottomNavigationBar extends StatefulWidget {
  @override
  _MyBottomNavigationBarState createState() => _MyBottomNavigationBarState();
}

class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
  final storage = FlutterSecureStorage();

  @override
  void initState(){
    super.initState();
    checkLoginStatus();
  }

  checkLoginStatus() async {
    String value = await storage.read(key: 'auth_token');
    if(value == null) {
      Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => AuthPage()), (Route<dynamic> route) => false);
    }
  }
  int _currentIndex = 0;
  final List<Widget> _children = [TaskPage(), CreatePage(), Profile_Page()];

  void onTappedBar(int index) {
    setState(() {

      _currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(

        resizeToAvoidBottomPadding: false,
        body: _children[_currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          onTap: onTappedBar,
          currentIndex: _currentIndex,

          backgroundColor: Color.fromRGBO(48, 63, 159, 1),

          items: [
            BottomNavigationBarItem(

              icon: new Icon(
                  Icons.dashboard,
                  size: 35,
                  color: Colors.white,
                  ),

              title: new Text(
                '',
                style: new TextStyle(fontSize: 0, color: Colors.white),
              ),
              activeIcon: Theme(
                data: ThemeData(
                  accentColor: Color.fromRGBO(70, 116, 190, 1),
                ),
                child: FloatingActionButton(
                  elevation: 0,
                  onPressed: () {},
                  child: Icon(
                      Icons.dashboard,
                      size: 35,
                      color: Colors.white,),
                ),
              ),
            ),
            BottomNavigationBarItem(
                icon: new Icon(
                  Icons.add_circle,
                  size: 35,
                  color: Colors.white,
                ),
                title: new Text(
                  '',
                  style: new TextStyle(color: Colors.white, fontSize: 0),
                ),
              activeIcon: Theme(
                data: ThemeData(
                  accentColor: Color.fromRGBO(70, 116, 190, 1),
                ),
                child: FloatingActionButton(
                  elevation: 0,
                  onPressed: () {},
                  child: Icon(
                    Icons.add_circle,
                    size: 35,
                    color: Colors.white,),
                ),
              ),

            ),
            BottomNavigationBarItem(
                icon: new Icon(Icons.account_circle,
                    size: 35, color: Colors.white),
                title: new Text(
                  '',
                  style: new TextStyle(fontSize: 0, color: Colors.white),
                ),
              activeIcon: Theme(
                data: ThemeData(
                  accentColor: Color.fromRGBO(70, 116, 190, 1),
                ),
                child: FloatingActionButton(
                  elevation: 0,
                  onPressed: () {},
                  child: Icon(
                    Icons.account_circle,
                    size: 35,
                    color: Colors.white,),
                ),
              ),
            ),
          ],
        ));
  }
}

创建页面.dart

import 'dart:convert';

import 'package:digitalpendal/main.dart';
import 'package:digitalpendal/screens/Authentication/AuthPage.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:localstorage/localstorage.dart';
import 'package:shared_preferences/shared_preferences.dart';


class CreatePage extends StatefulWidget {
  @override
  _CreatePageState createState() => _CreatePageState();
}

class _CreatePageState extends State<CreatePage> {


 // final LocalStorage storage = new LocalStorage('some_key');
  final formKey = new GlobalKey<FormState>();

  String _name;
  String _description;
  String _countPeople;
  String _cost;
  String _executePeriod;
  String value;



  final _sizeTextBlack = const TextStyle(fontSize: 20.0, color: Colors.black);
  final _sizeTextWhite = const TextStyle(fontSize: 20.0, color: Colors.white);
  final storage = FlutterSecureStorage();



  @override
  void initState(){
    super.initState();
    checkLoginStatus();
  }

  checkLoginStatus() async {
    String value = await storage.read(key: 'auth_token');
    if(value == null) {
      Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => AuthPage()), (Route<dynamic> route) => false);
    }
  }


  BuildContext _context;
  @override
  Widget build(BuildContext context) {
    _context = context;
    return new MaterialApp(
        debugShowCheckedModeBanner: false,
        home: new Scaffold(
          resizeToAvoidBottomPadding: false,
          body: new Center(
            child: SingleChildScrollView(
              child: new Form(
                  key: formKey,
                  child: new Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      new Padding(padding: EdgeInsets.only(top: 20.0)),
                      new Container(
                        child: new TextFormField(
                          decoration: new InputDecoration(
                            labelText: "Название работы",
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                          maxLines: 1,
                          validator: (val) =>
                          val.length < 2 ? 'Ввидите название' : null,
                          onSaved: (val) => _name = val,
                          style: _sizeTextBlack,
                        ),
                        width: 340.0,
                        height: 50,
                        margin: new EdgeInsets.only(top: 20.0),
                      ),
                      new Container(
                        child: new TextFormField(
                          decoration: new InputDecoration(
                            labelText: "Сколько людей нужно",
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                          maxLines: 1,
                          validator: (val) =>
                          val.length < 0 ? 'количество меньше 0' : null,
                          onSaved: (val) => _countPeople = val,
                          style: _sizeTextBlack,
                        ),
                        width: 340.0,
                        height: 50,
                        margin: new EdgeInsets.only(top: 20.0),
                      ),
                      new Container(
                        child: new TextFormField(
                          decoration: new InputDecoration(
                            labelText: "Ввидите сумму",
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                          maxLines: 1,
                          validator: (val) =>
                          val.length < 0 ? 'сумма мала' : null,
                          onSaved: (val) => _cost = val,
                          style: _sizeTextBlack,
                        ),
                        width: 340.0,
                        height: 50,
                        margin: new EdgeInsets.only(top: 20.0),
                      ),
                      new Container(
                        child: new TextFormField(
                          decoration: new InputDecoration(
                            labelText: "Срок исполнения",
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                          maxLines: 1,
                          validator: (val) =>
                          val.length < 0 ? 'Введиnt срок выполнения' : null,
                          onSaved: (val) => _executePeriod = val,
                          style: _sizeTextBlack,
                        ),
                        width: 340.0,
                        height: 50,
                        margin: new EdgeInsets.only(top: 20.0),
                      ),
                      new Container(
                        child: new TextFormField(
                          decoration: new InputDecoration(
                            labelText: "краткое описание",
                            fillColor: Colors.white,
                            border: new OutlineInputBorder(
                              borderRadius: new BorderRadius.circular(25.0),
                              borderSide: new BorderSide(),
                            ),
                            //fillColor: Colors.green
                          ),
                          maxLines: 1,
                          validator: (val) =>
                          val.length < 2 ? 'Введите описание' : null,
                          onSaved: (val) => _description = val,
                          style: _sizeTextBlack,
                        ),
                        width: 340.0,
                        height: 50,
                        margin: new EdgeInsets.only(top: 20.0),
                      ),

                      new Padding(padding: new EdgeInsets.only(top: 50.0)),
                      new MaterialButton(
                        onPressed: submit,
                        color: Theme.of(context).accentColor,
                        height: 50.0,
                        minWidth: 150.0,
                        child: new Text(
                          "Создать",
                          style: _sizeTextWhite,
                        ),
                      ),
                    ],
                  )),
            ),
          ),
        ));
  }

  void submit() {
    final form = formKey.currentState;
    if (form.validate()) {
      form.save();
      performLogin(form);
    }
  }



  void performLogin(form) async {
    hideKeyboard();

    http.Response response = await http.post(
        Uri.encodeFull(
            'http://192.168.0.104:8000/api/v1/jobs/job/create/'),
        headers: {
          'Accept': 'application/json',
          //'Authorization': 'Token 82b6a5bcf7ad37f45de2a3e89bfea52f23bfb87a'//admin worked hardcore
          'Authorization':  value
        },
        body: {
          'name': _name,
          'description': _description,
          'count_people': _countPeople,
          'cost': _cost,
          'execute_period': _executePeriod
        });
    if (response.statusCode == 201) {
      //storage.setItem('user', jsonEncode(response.body));
      hideKeyboard();
      Navigator.push(_context,
          new MaterialPageRoute(builder: (context) => new MyBottomNavigationBar()));
    }
  }



  void hideKeyboard() {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }
}
flutter
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2020-01-19 22:22:15 +0000 UTC

错误:“使用不包含导航器的上下文请求导航器操作。”

  • 0

痛了好久,不知道怎么解决。应用程序启动,但是理论上,当您单击 gridView 元素时,应该会显示一个带有图片的窗口,但是当您单击它时,它会显示错误异常捕获的手势“Navigator operation requested with a context that does not包括一个导航器。”

主要.dart

import 'package:flutter/material.dart';
import 'details.dart';
import 'services.dart';
import 'album.dart';
import 'cell.dart';
import 'dart:async';

void main()=>runApp(GridViewDemo());

class GridViewDemo extends StatefulWidget {

  final String title = "Photos";

  @override
  GridViewDemoState createState() => GridViewDemoState();

}

class GridViewDemoState extends State<GridViewDemo> {
  //
  StreamController<int> streamController = new StreamController<int>();

  gridview(AsyncSnapshot<List<Album>> snapshot) {
      return Padding(
        padding: EdgeInsets.all(5.0),
        child: GridView.count(
          crossAxisCount: 2,
          childAspectRatio: 1.0,
          mainAxisSpacing: 4.0,
          crossAxisSpacing: 4.0,
          children: snapshot.data.map(
                (album) {
              return GestureDetector(
                child: GridTile(
                  child: AlbumCell(album),
                ),
                onTap: () {
                 goToDetailsPage(context, album);
                },
              );
            },
          ).toList(),
        ),

      );
  }

  goToDetailsPage(BuildContext context, Album album) {
    Navigator.push(
      context,
      MaterialPageRoute(
        fullscreenDialog: true,
        builder: (BuildContext context) => GridDetails(
          curAlbum: album,
        ),
      ),
    );

  }


  circularProgress() {
    return Center(
      child: const CircularProgressIndicator(),
    );
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: StreamBuilder(
            initialData: 0,
            stream: streamController.stream,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              return Text('${widget.title} ${snapshot.data}');
            },
          )),
       body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Flexible(
            child: FutureBuilder<List<Album>>(
              future: Services.getPhotos(),
              builder: (context, snapshot) {
                // not setstate here
                //
                if (snapshot.hasError) {
                  return Text('Error ${snapshot.error}');
                }
                //
                if (snapshot.hasData) {
                  streamController.sink.add(snapshot.data.length);
                  // gridview
                  return gridview(snapshot);
                }

                return circularProgress();
              },
            ),
          ),
        ],
      ),
    ),
    );
  }

  @override
  void dispose() {
    streamController.close();
    super.dispose();
  }
}

细胞飞镖

import 'package:flutter/material.dart';
import 'album.dart';

class AlbumCell extends StatelessWidget {
  const AlbumCell(this.album);
  @required
  final Album album;

  @override
  Widget build(BuildContext context) {
    return Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10.0),
      ),
      color: Colors.white,
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Container(
          alignment: Alignment.center,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Flexible(
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(10.0),
                  child: Hero(
                    tag: "image${album.id}",
                    child: FadeInImage.assetNetwork(
                      placeholder: "images/no_image.png",
                      image: album.thumbnailUrl,
                      width: 100,
                      height: 100,
                    ),
                  ),
                ),
              ),
              Padding(
                padding: EdgeInsets.all(10.0),
                child: Text(
                  album.title,
                  maxLines: 1,
                  softWrap: true,
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontSize: 20.0,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

专辑.dart

class Album {


int albumId;
  int id;
  String title;
  String url;
  String thumbnailUrl;

  Album({this.albumId, this.id, this.title, this.url, this.thumbnailUrl});

  factory Album.fromJson(Map<String, dynamic> json) {
    return Album(
      albumId: json['albumId'] as int,
      id: json['id'] as int,
      title: json['title'] as String,
      url: json['url'] as String,
      thumbnailUrl: json['thumbnailUrl'] as String,
    );
  }
}

服务.dart

    import 'dart:convert';
import 'package:http/http.dart' as http;
import 'album.dart';

class Services {
  static const String url = "https://jsonplaceholder.typicode.com/photos";

  static Future<List<Album>> getPhotos() async {
    try {
      http.Response response = await http.get(
        Uri.encodeFull(url)
      );
      if (response.statusCode == 200) {
        List<Album> list = parsePhotos(response.body);
        return list;
      } else {
        throw Exception("Error");
      }
    } catch (e) {
      throw Exception(e.toString());
    }
  }

  static List<Album> parsePhotos(String responseBody) {
    final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
    return parsed.map<Album>((json) => Album.fromJson(json)).toList();
  }
}

细节.dart

import 'package:flutter/material.dart';
import 'album.dart';

class GridDetails extends StatefulWidget {
  final Album curAlbum;
  GridDetails({@required this.curAlbum});

  @override
  GridDetailsState createState() => GridDetailsState();
}

class GridDetailsState extends State<GridDetails> {
  //
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        margin: EdgeInsets.all(30.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Hero(
              tag: "image${widget.curAlbum.id}",
              child: FadeInImage.assetNetwork(
                placeholder: "images/no_image.png",
                image: widget.curAlbum.url,
              ),
            ),
            SizedBox(
              height: 30.0,
            ),
            OutlineButton(
              child: Icon(Icons.close),
              onPressed: () => Navigator.of(context).pop(),
            ),
          ],
        ),
      ),
    );
  }
}
android
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2020-11-02 22:48:37 +0000 UTC

如何在颤动中使用共享首选项保存开关小部件状态?

  • 1

有一个 ChangeTheme 类,它有一个切换小部件,可以改变应用程序的主题,但是如果你转到另一个屏幕,然后再次返回带有开关的屏幕,它将不会再次处于活动状态。此外,如果您关闭应用程序,则由开关设置的主题将被重置。如何解决?

更改主题.dart

import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todo/theme.dart';
import 'package:provider/provider.dart';



class ChangeTheme extends StatefulWidget{

  ChangeTheme({Key key, this.title}): super(key: key);
  final String title;
  @override
  MyState createState() => new MyState ();

}


class MyState extends State<ChangeTheme>{
  bool val = false;
  String message = "смена темы";
  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

  @override
  Widget build(BuildContext context){
    set();
    return new Scaffold(

        appBar: AppBar(
          title: Text('Настройки'),
        ),
        body: Container(
            child: Column(
              children: <Widget>[
               new Switch(
                 value: val,
                 onChanged: (bool e) => setState(() => something(e)),
                ),
                new Text (message),

                ],
              ),
      ),
    );
  }

 void something(bool e) {
   ThemeChanger _themeChanger = Provider.of<ThemeChanger>(context);
    setState(() {

      if (e){
        _themeChanger.setTheme(ThemeData.dark());
        message = "Темнаяя тема";
        val = e;
        get();

      } else {
        _themeChanger.setTheme(ThemeData.light());
        message = "Светлая тема";
        val = e;
        get();
      }
    });
 }
  get() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    final myBool = prefs.getBool('my_bool_key') ?? false;
  }
  set() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setBool('my_bool_key', true);
  }

}

主要.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'theme.dart';
import 'ChangeTheme.dart';
import 'Constants.dart';

void main() async => runApp(new TodoApp());

class TodoApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ThemeChanger>(
      builder: (_) => ThemeChanger(ThemeData.light()),
      child: new MaterialAppWithTheme (
      ),
    );
  }
}

class MaterialAppWithTheme extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    final theme = Provider.of<ThemeChanger>(context);

    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: new TodoList(),
      theme: theme.getTheme(),
    );
  }

}

class TodoList extends StatefulWidget {
  @override
  createState() => new TodoListState();
}

class TodoListState extends State<TodoList> {

  List<String> _todoItems = [];



  @override
  Widget build(BuildContext context) {
    _getPrefs();
    return new Scaffold(
      appBar: new AppBar(title: new Text('Список задач'),
      actions: <Widget>[
      PopupMenuButton<String>(
       onSelected: choiceAction ,
        itemBuilder: (BuildContext context){
         return Constants.choices.map((String choice){
            return PopupMenuItem<String>(
            value: choice,
              child: Text(choice),
            );
         }).toList();
        },
      )
      ]),
      body: _buildTodoList(),

      floatingActionButton: new FloatingActionButton(
          onPressed: _addTodoItem,
          tooltip: 'Add task',
          child: new Icon(Icons.add)),
    );
  }

  Widget _buildTodoList() {
    return new ListView.builder(itemBuilder: (context, index) {
      if (index < _todoItems.length) {
        return _buildTodoItem(_todoItems[index], index);
      }
    });
  }


 void choiceAction(String choice){
    if (choice == Constants.ChangeTheme){
      _changeTheme();


    }

    else if (choice == Constants.OffAd){
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return new AlertDialog(
                title: new Text('Хочешь отключить рекламу?\n\n'
                    'Разработчку и дизайнеру тоже хочеца кушатб, '
                    'поэтому для отключения рекламы отправь деняк. '),
                actions: <Widget>[
                  new FlatButton(
                      child: new Text('подробнее'),
                      onPressed: () => Navigator.of(context).pop()),
                  new FlatButton(
                      child: new Text('нет я жмот'),
                      onPressed: () => Navigator.of(context).pop()),
                ]);
          });


    } else if (choice == Constants.info){
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return new AlertDialog(
                title: new Text('Todo\n'
                                'Разбработчик:  \n'
                                'Дизайнер:  \n'
                                ),
                actions: <Widget>[
                  new FlatButton(
                      child: new Text('оценить'),
                      onPressed: () => Navigator.of(context).pop()),
                  new FlatButton(
                      child: new Text('отмена'),
                      onPressed: () => Navigator.of(context).pop()),
                ]);
          });

    }
 }

 void _changeTheme(){
   Navigator.push(context,
       new MaterialPageRoute(
           builder: (context) => new ChangeTheme()));
 }



  Widget _buildTodoItem(String todoText, int index) {
    return new ListTile(
        title: new Text(todoText), onTap: () => _removeTodoItem(index));
  }

  void _addTodoItem() {
    // Push this page onto the stack
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      return new Scaffold(
          appBar: new AppBar(title: new Text('добавление задачи')),
          body: new TextField(
            autofocus: true,
            onSubmitted: (val) {
              _addItem(val);
              Navigator.pop(context); // Close the add todo screen
            },
            decoration: new InputDecoration(
                hintText: 'Введите вашу задачу',
                contentPadding: const EdgeInsets.all(16.0)),
          ));
    }));
  }

  void _addItem(String task) {
    if (task.length > 0) {
      setState(() => _todoItems.add(task));
      _setPrefs();
    }
  }

  void _removeTodoItem(int index) {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return new AlertDialog(
              title: new Text('Задача "${_todoItems[index]}" выполнена?'),
              actions: <Widget>[
                new FlatButton(
                    child: new Text('отмена'),
                    onPressed: () => Navigator.of(context).pop()),
                new FlatButton(
                    child: new Text('выполнена'),
                    onPressed: () {
                      _removeItem(index);
                      Navigator.of(context).pop();
                    })
              ]);
        });
  }

  void _removeItem(int index) {
    setState(() => _todoItems.removeAt(index));
    _setPrefs();
  }

  void _setPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setStringList('TodoList', _todoItems);
  }

  void _getPrefs() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    if (prefs.getStringList('TodoList') != null)
      _todoItems = prefs.getStringList('TodoList');
  }

}

主题.dart

import 'package:flutter/material.dart';

class ThemeChanger with ChangeNotifier {
  ThemeData _themeData;

  ThemeChanger(this._themeData);

  getTheme() => _themeData;
  setTheme(ThemeData theme) {
    _themeData = theme;

    notifyListeners();
  }
}

常量.dart

 class Constants {
  static const String ChangeTheme = 'Настройки';
  static const String info = 'Информация';
  static const String OffAd = 'Отключить рекламу';

  static const List<String> choices = <String>[
    ChangeTheme,
    info,
    OffAd
  ];

}
android
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2020-09-05 15:55:52 +0000 UTC

在应用关闭时保存列表视图数据

  • 1

我有一个用颤振编写的 TODO 应用程序,我希望在关闭应用程序时保存列表视图中添加的文本。听说可以添加共享偏好,但是最近在编程,不知道怎么实现。main.dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';


void main() => runApp(new TodoApp());


class TodoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Todo List',
        home: new TodoList()
    );
  }
}

class TodoList extends StatefulWidget {
  @override
  createState() => new TodoListState();
}

class TodoListState extends State<TodoList> {
  String _haveStarted3Times = '';
  List<String> _todoItems = [];

  void _addTodoItem(String task) {
    if(task.length > 0) {

      setState(() => _todoItems.add(task));
    }
  }

  void _removeTodoItem(int index) {
    setState(() => _todoItems.removeAt(index));
  }

  void _promptRemoveTodoItem(int index) {
    showDialog(
        context: context,
        builder: (BuildContext context) {
          return new AlertDialog(
              title: new Text('Задача "${_todoItems[index]}" выполнена?'),
              actions: <Widget>[
                new FlatButton(
                    child: new Text('отмена'),
                    onPressed: () => Navigator.of(context).pop()
                ),
                new FlatButton(
                    child: new Text('выполнена'),
                    onPressed: () {
                      _removeTodoItem(index);
                      Navigator.of(context).pop();
                    }
                )
              ]
          );
        }
    );
  }


  Widget _buildTodoList() {
    return new ListView.builder(
      itemBuilder: (context, index) {
        if(index < _todoItems.length) {
          return _buildTodoItem(_todoItems[index], index);
        }
      },
    );
  }

  Widget _buildTodoItem(String todoText, int index) {
    return new ListTile(
        title: new Text(todoText),
        onTap: () => _promptRemoveTodoItem(index)
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
          title: new Text('Todo List')
      ),
      body: _buildTodoList(),
      floatingActionButton: new FloatingActionButton(
          onPressed: _pushAddTodoScreen,
          tooltip: 'Add task',
          child: new Icon(Icons.add)
      ),
    );
  }

  void _pushAddTodoScreen() {
    // Push this page onto the stack
    Navigator.of(context).push(
        new MaterialPageRoute(
            builder: (context) {
              return new Scaffold(
                  appBar: new AppBar(
                      title: new Text('добавление задачи')
                  ),
                  body: new TextField(
                    autofocus: true,
                    onSubmitted: (val) {
                      _addTodoItem(val);
                      Navigator.pop(context); // Close the add todo screen
                    },
                    decoration: new InputDecoration(
                        hintText: 'Введите вашу задачу',
                        contentPadding: const EdgeInsets.all(16.0)
                    ),
                  )
              );
            }
        )
    );
  }
}
listview
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2022-10-10 15:11:57 +0000 UTC

下载 php 脚本而不是处理它

  • 1

我有一个带有 centos 7 的虚拟服务器,安装了 nginx + php-fpm,我无法配置 nginx 配置,以便在切换到域时处理 .php 文件,但是,在切换到域时,它提供下载一个带有 php 脚本的文件。

server {
    listen   80;
    server_name  myapptest.gq;
        root   /usr/share/nginx/html;
        index  index.php;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    #location / {
     #   root   /usr/share/nginx/html;
      #  index  index.php index.html index.htm;
    #}

        #location / {
        #   try_files $uri $uri/ /index.php?q=$uri&$args;
        #}
    #location ~* ^.+.(js|css|png|jpg|jpeg|gif|ico)$ {
        #   access_log        off;
        #   expires           max;
        #}

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root php;
        #fastcgi_param  DOCUMENT_ROOT    /myapptest.gq;
        #fastcgi_pass unix:/var/run/php-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
       include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        root php;
        #fastcgi_param  DOCUMENT_ROOT    /myapptest.gq;
        #fastcgi_pass unix:/var/run/php-fpm.sock;
        #fastcgi_pass 127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
       include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
nginx centos
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2020-11-30 10:48:46 +0000 UTC

在按钮上创建活动

  • 0

有一个“创建任务”按钮,当您单击它时,会出现“俄语”按钮,如果您单击它,则会创建一个新活动并将我们转移到它。问题:如何实现,以便在单击按钮时,会出现一个附有新活动的按钮。

android-studio
  • 1 个回答
  • 10 Views
Martin Hope
fantik
Asked: 2020-05-11 16:26:01 +0000 UTC

按钮出现在 BottomNavigationView

  • 0

创建BottomTabActivity和一个带有 xml 文件的片段。我连接了所有这些,当我在片段的 xml 文件中创建一个常规按钮时,它会出现在这个 BottomTab 中,无论我放在哪里。我不知道怎么了。在此处输入图像描述

 MainActivity.xml

<?xml version="1.0" encoding="utf-8"?>
  <android.support.constraint.ConstraintLayout  xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.design.widget.BottomNavigationView
    android:id="@+id/navigation"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:background="?android:attr/windowBackground"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:menu="@menu/navigation" />

</android.support.constraint.ConstraintLayout>


  MainActivity.class



public class MainActivity extends AppCompatActivity {



private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                  account account = new account();
                FragmentManager manager = getSupportFragmentManager();
                manager.beginTransaction().replace(R.id.navigation, account, account.getTag()).commit();
                return true;
            case R.id.navigation_dashboard:

                return true;
            case R.id.navigation_notifications:

                return true;
        }
        return false;
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}

}

android
  • 1 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5