Проблема с Android Studio и Main Activity.kt, ожидающими объявления члена

Я пытался учиться с помощью следующих руководств YouTube. Я использую Android Studio 3.1 Canary, и я дохожу до той же точки в учебниках и застреваю. Например, если вы перейдете к этому руководству YouTube https://youtu.be/3RMboPhUbmg?t=210 на отметке 3:30 мин.

Когда они вводят MaterialSearchView searchView; он отображается для меня с красным подчеркиванием, говорящим «ожидание объявления члена», и независимо от того, сколько поисков я пытаюсь, я не могу найти ответ. Каково решение этой ошибки? Спасибо

Это код, содержащийся в файле Main2Activity.kt. Результатом должен быть вызов или знание объектов панели инструментов и материалов.

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.Toolbar
import com.miguelcatalan.materialsearchview.MaterialSearchView
import kotlinx.android.synthetic.main.activity_main2.*

class Main2Activity : AppCompatActivity () {
    **MaterialSearchView searchView;**  "expecting member declaration error"
    **Toolbar  toolbar;** "expecting member declaration error"
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        toolbar=(Toolbar()) findViewbyId(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
    *private void searchViewCode()
    {
        searchView=(MaterialSearchView)findViewById(R.id.search_view);
    }
}

person wolfgang    schedule 13.11.2017    source источник
comment
Добро пожаловать в stackoverflow.com. Пожалуйста, покажите нам фрагмент кода, ожидаемый результат и ошибку.   -  person Logain    schedule 13.11.2017
comment
Старайтесь не ссылаться на внешние источники и создать минимальный проверяемый пример stackoverflow.com/help/mcve.   -  person Logain    schedule 13.11.2017


Ответы (4)


1) Поймите синтаксис вашего языка

Ваш учебник на Java. Вы пытаетесь писать на Котлине. Java и Kotlin имеют разный синтаксис, и если вы дословно воспроизведете это руководство в Kotlin, это не удастся.

Следуйте инструкциям и напишите свой код на Java. Переключитесь на Kotlin позже, когда будете более уверены в том, что делаете. Сосредоточьтесь на чем-то одном.

2) Найдите просмотры в нужное время

Объект Activity создается для вас фреймворком с общедоступным пустым конструктором. На данный момент просмотров нет. Если вы вызовете findViewById в любое время до setContentView, он вернет null и вылетит, если вы попытаетесь присвоить его переменной, не допускающей значение NULL.

Вышесказанное относится как к Java, так и к Kotlin.

Для Java следуйте руководству. Это должно выглядеть примерно так:

Toolbar toolbar; // Declare the variable here so it's accessible outside of onCreate.

@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2); // Inflate view hierarchy.
    toolbar = (Toolbar) view.findViewById(R.id.toolbar); // Find your views.
    setSupportActionBar(toolbar);
}

В Котлине есть несколько вариантов.

Вы можете использовать модификатор lateinit, который позволяет объявить ненулевую переменную, но назначить ее позже в onCreate.

lateinit var toolbar: Toolbar

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
    toolbar = findViewById(R.id.toolbar) as Toolbar
    setSupportActionBar(toolbar)
}

Или вы можете использовать lazy делегата. Переменная будет назначена при первом доступе к ней.

val toolbar: Toolbar by lazy(LayzThreadSafetyMode.NONE) {
    toolbar = findViewById(R.id.toolbar) as Toolbar
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
    setSupportActionBar(toolbar)
}

Не используйте делегат. Он создает ненужный объект держателя для каждого lazy, это расточительно.

Вы также можете использовать расширения Kotlin для Android и просто обращаться к toolbar напрямую, потому что все тяжелые подъем сделан для вас.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
    setSupportActionBar(toolbar)
}

В качестве альтернативы вы можете использовать привязку представления, доступную начиная с Android Studio 3.6 Canary 11.

private lateinit var binding: ActivityMain2Binding

@Override
fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(savedInstanceState)
    binding = ActivityMain2Binding.inflate(layoutInflater)
    setContentView(binding.root)
    setSupportActionBar(binding.toolbar)
}

Вы получаете высокую производительность первого варианта и надежную безопасность типов.

person Eugen Pechanec    schedule 14.11.2017

Кажется, вы объявляете свои переменные searchView и toolbar, используя синтаксис Java, а не синтаксис Kotlin, поэтому компилятор не понимает, что вы объявляете.

Поэтому измените объявление на:

var searchView: MaterialSearchView? = null
val toolbar: Toolbar = view.findViewById(R.id.toolbar) as Toolbar 

или, если вы используете расширения Kotlin для Android, вы сможете получить панель инструментов следующим образом (используя идентификатор представления напрямую):

person erafn    schedule 13.11.2017
comment
Не делайте этого: val toolbar: Toolbar = toolbar Нет смысла, вы уже можете получить доступ к toolbar. В качестве бонуса расширения Kotlin уже включают кэширование найденных представлений. - person Eugen Pechanec; 13.11.2017
comment
Я изменил строку @erafn панели инструментов val: Toolbar = view.findViewById(R.id.toolbar) as Toolbar на приведенную ниже, и на ней не отображаются красные подчеркивания. val toolbar: Toolbar = findViewById(R.id.toolbar) Также первая строка в ответе erafn работала отлично. - person wolfgang; 14.11.2017
comment
val toolbar: Toolbar не будет работать, потому что действие создание экземпляра происходит задолго до onCreate. Поскольку перед вызовом setContentView нет иерархии представлений, toolbar будет нулевым. И поскольку переменная имеет тип Toolbar (не обнуляемый), ваше приложение вылетит при запуске с KotlinNullPointerException. - person Eugen Pechanec; 14.11.2017
comment
Вы правы @Eugen Pechanec, это была ошибка, и я ее удалил. - person erafn; 15.11.2017

В моем случае проблема заключалась в невидимом символе из-за копирования и вставки из .PDF.

Обратите внимание, что между '{' и 'onClick' в приведенном ниже фрагменте есть два символа.

setOnClickListener { ​onClick(item) }

Это причина моих кошмаров.

person ferreiraiso    schedule 28.08.2018
comment
Я не думаю, что это правильный ответ. Имхо, очевидно, что у OP нет проблемы с копированием/вставкой (а также принятый ответ без каких-либо проблем с копированием/вставкой). Это должен быть комментарий, а не ответ. - person colidyre; 29.08.2018
comment
Спасибо @ferreiraiso! Я бы потерял много времени, пытаясь понять причину, если бы не увидел ваш ответ. - person Oya Canli; 13.08.2019
comment
между прочим, у меня была такая же проблема, и это помогло мне, удалив некоторые пробелы - person sobelito; 31.12.2019

Основная проблема заключается в синтаксисе. Всякий раз, когда вы обновляете серию 3 до 4. Синтаксис Java преобразуется в синтаксис Kotlin.

Синтаксис Kotlin:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
   }
   }

Синтаксис Java:

@Override
public void onCreate(@Nullable final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2); // Inflate view hierarchy.
   }
   }

Если вы хотите изменить синтаксис Kotlin на синтаксис Java.

Вернулся к панели программирования mainActivity после этого ИНСТРУМЕНТЫ -> KOTLIN -> Показать байт-коды KOTLIN Затем проверьте цель JVM 8 и отметьте ее.

После этого неверный catch/Restart

Проблема решена.

person Amir Sharfu    schedule 08.09.2020