Notas do "Guia de aplicação do Jetpack"

Modelo de visualização

reter dados da IU

A atividade/fragmento exibe apenas dados e lida com a interação do usuário.

ViewModel contém dados da IU.

vida útil

A reconstrução da Activity não afetará o ciclo de vida do ViewModel.

Existe apenas uma função de ciclo de vida do ViewModel onCleared()e essa função será chamada somente quando a página representada pela Activity for destruída.
insira a descrição da imagem aqui

Contexto de cotação do ViewModel

O ciclo de vida do ViewModel é maior que o do Activity, portanto você não deve manter uma referência ao Activity no ViewModel, caso contrário, causará um vazamento de memória.

O ViewModel não recomenda a introdução de Activity, mas e se o Context for necessário no ViewModel? Um dos seguintes métodos pode ser utilizado: 1.
Use 2. Use AndroidViewModel, que é uma subclasse de ViewModel, que recebe Application como Context internamente;Context.getApplicationContext()

Instanciação do ViewModel

XXXViewModel mXXXViewModel = new ViewModelProvider(this).get(XXXViewModel.class);

A diferença entre ViewModel e onSaveInstanceState()

  1. Diferença de dados
    onSaveInstanceState() pode salvar apenas uma pequena quantidade de dados da IU que podem ser serializados e não pode salvar grandes dados, como Bitmap.
    ViewModel não tem tais restrições.

  2. A persistência de dados
    onSaveInstanceState() pode salvar uma pequena quantidade de dados da UI nas duas situações a seguir:
    ① O processo do aplicativo é encerrado devido a limitações de memória quando está em segundo plano.
    ② Mudanças de configuração.

ViewModels só podem persistir dados em caso de destruição em alterações de configuração, e não em processos encerrados.

Dados ao vivo

usar

LiveData pode ser entendido como um contêiner de dados. Ele agrupa os dados para que eles se tornem um observador e, quando os dados mudarem, o observador possa ser notificado.

ViewModel contém dados da UI, e Activity/Fragment é responsável por exibir os dados. Se os dados da UI mudarem, LiveData notifica Activity/Fragment para atualizar os dados. Portanto, LiveData geralmente é usado em ViewModel.

uso básico

LiveData é uma classe abstrata e não pode ser usada diretamente. Normalmente usamos sua subclasse MutableLiveData.

Observe os dados agrupados pelo LiveData por meio do método LiveData.observe(). Por outro lado, quando queremos modificar os dados agrupados pelo LiveData, podemos fazê-lo através do método LiveData.postValue()/LiveData.setValue(). postValue() é chamado em thread não UI e setValue() é chamado em thread UI.

atualização de notificação

LiveData pode perceber o ciclo de vida da página, e somente quando a página estiver no estado ativo (Lifecycle.State.STARTED ou Lifecycle.State.RESUMED) a notificação do LiveData será recebida. Se a página for destruída (Lifecycle.State. DESTROYED), então o LiveData limpará automaticamente as associações com as páginas, evitando assim vazamentos de memória.

Normalmente, o LiveData só envia atualizações quando os dados mudam e apenas para observadores ativos. Uma exceção a esse comportamento é que os observadores também recebem atualizações quando passam de inativos para ativos. Além disso, se o observador mudar de inativo para ativo uma segunda vez, ele só receberá atualizações se o valor tiver mudado desde a última vez que ficou ativo.

LiveData.observeForever() é usado da mesma forma que observe, a diferença é que quando os dados mudam, não importa em que estado a página esteja, ela pode receber notificações. Portanto, você deve chamar removeObserver() após o uso para remover o observador e evitar vazamentos de memória.

ViewModel+LiveData implementa comunicação entre fragmentos

public class OneFragment extends Fragment {
    
    

	public void onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
    
		/*
		关键在于ViewModelProvider的构造函数传入的是getActivity()而不是Fragment.this,
		这样才能保证每个Fragment得到的是同一个ViewModel,从而共享LiveData
		*/
		XXXViewModel mXXXViewModel = new ViewModelProvider(getActivity()).get(XXXViewModel.class);
	}
}

//TwoFragment与OneFragment类似

resumo

A essência do LiveData é o modo observador + ciclo de vida de percepção.

Ligação de dados

fácil de usar

  1. Iniciar ligação de dados
android {
    
    
	……
	dataBinding {
    
    
		enabled = true;
	}
}
  1. Arquivo de layout de tags
    Adicione tags fora da raiz do arquivo de layout <layout>. O objetivo disso é instruir a biblioteca DataBinding para gerar a classe Binding correspondente ao arquivo de layout.
<layout xmlns:android="http://schemas.android.com/apk/res/android">
	/*
	以下是实际布局
	……
	*/
</layout>
  1. Definir variáveis ​​de layout
<layout xmlns:android="http://schemas.android.com/apk/res/android">
	<data>
		<variable
			name = "变量名"
			type = "类全名"/>
		/*
		或者使用<import>标签引入类
		<import type = "类全名"/>
		<variable
			name = "变量名"
			type = "类名称"/>
		*/
		
	</data>
	/*
	以下是实际布局
	……
	*/
</layout>
  1. Obtenha a classe Binding
//该方法给Activity设置布局文件的同时,返回Binding类。
XXXBinding mXXXBinding = DataBindingUtil.setContentView(this, R.layout.xxx);
  1. Atribuição de variáveis ​​de layout
    A vinculação fornece dois métodos de atribuição de valores a variáveis ​​de layout:
    ①Método geral: XXXBinding.setVariable(BR.变量名, 变量);
    ②Método de atribuição para variáveis ​​de layout específicas:XXXBinding.set变量名(变量)

  2. Expressão de layout
    O formato de uma expressão de layout: @{}.
    Por exemplo: @{布局变量.字段},@{方法调用的表达式}

<data>
	<import type = "xxx.xxx.TestUtil"/>
	<variable
		name = "book"
		type = "xxx.xxx.Book"/>
</data>

<!-- 在布局中引用静态类-->
<TextView
	android:text="@{TestUtil.getText()}"/>

<TextView
	android:text="@{book.name}"/>

As expressões de layout são muito mais do que esses usos. Para obter detalhes, consulte: Explicação detalhada da vinculação de dados (2) - Expressões de layout e vinculação

  1. Aparência final da atividade
public class TestActivity extends Activity {
    
    
	protected void onCreate(Bundle savedInstanceState) {
    
    
		super.onCreate(savedInstanceState);
		XXXBinding mXXXBinding = DataBindingUtil.setContentView(this, R.layout.xxx);
		Book book = new Book();
		book.name = "Jetpack应用指南";
		mXXXBinding.setBook(book);
	}
}

vinculação de evento

DataBinding suporta o uso de expressões de layout para lidar com respostas de eventos View.
Método específico: atribua uma expressão de layout ao atributo de evento de View no arquivo de layout.
Isto equivale a usar a expressão de layout para implementar o retorno de chamada do ouvinte correspondente. Essa prática é conhecida como vinculação de eventos .

Correspondência entre atributos de eventos e ouvintes

O nome do atributo do evento depende do nome do método listener. Por exemplo, View.OnClickListener possui onClick()o método e View.OnLongClickListener possui onLongClick()o método, portanto, as propriedades do evento são android:onClick, android:onLongClick.
Para o evento de clique, a fim de evitar o conflito de múltiplos eventos de clique, o Google também define alguns processamentos de eventos especiais, como:

Aula Como configurar o ouvinte propriedades na ligação
Visualização de pesquisa setOnSearchClickListener(View.OnClickListener) android:onSearchClick
Controles de Zoom setOnZoomInClickListener(View.OnClickListener) android:onZoomIn
Controles de Zoom setOnZoomOutClickListener(View.OnClickListener) android:onZoomOut

Existem dois tipos de expressões de layout para vinculação de eventos: método de referência e ouvinte de vinculação .

método de referência

Use variáveis ​​de layout para responder a eventos. Este método requer que os parâmetros e o valor de retorno correspondam aos do ouvinte . Se os parâmetros ou o valor de retorno não corresponderem, um erro será relatado em tempo de compilação.

public class EventHandler {
    
    

	public void onClickHandle(View view) {
    
    
		System.out.println("按钮被点击了");
	}
}


<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="eventHandler"
            type="xxx.xxx.EventHandler" />
    </data>
    ...
    <Button
           ...
            android:onClick="@{eventHandler::onClickHandle}"
           ... />
    ...
</layout>

Ao usar o Método de Referência, o ouvinte gerado encapsula a chamada do método para a variável de layout. O objeto ouvinte é criado e atribuído quando a variável de layout é definida. Se a variável de layout for nula, o ouvinte não será criado.

/*
“引用方法”的监听器创建原理如下伪代码所示
伪代码是在运行时运行的。
*/
xxxBinding.setEventHandler(EventHandler eventHandler) {
    
    
	if(eventHandler != null) {
    
    
		button.setOnClickListener(new OnClickListener() {
    
    
				public void onClick(View view) {
    
    
					eventHandler.onClickHandle(view);
				}
		});
	}
}

vincular ouvinte

Use lambdas em arquivos de layout para responder a eventos. O método requer apenas que o valor de retorno corresponda ao valor de retorno esperado do ouvinte .

public class Tester {
    
    
	
	public boolean testLongClick() {
    
    
		return false;
	}
}

<Button
   ...
   android:onClick="@{()->tester.testLongClick()}"
   ... />

Os ouvintes de ligação permitem parâmetros personalizados.

public class Tester {
    
    

	public boolean testLongClick(View v, String info) {
    
    
		Toast.makeText(v.getContext(), info, Toast.LENGTH_LONG).show();
	}
}

<Button
   ...
   android:onClick="@{(view)->tester.testLongClick(view, '你好')}"
   ... />

"Bind Listener" criará automaticamente o ouvinte necessário e registrará eventos para ele durante a compilação (o ouvinte é criado no início e não será julgado se a variável de layout está vazia até ser acionada, e nenhuma execução será executada se está vazio. operar)

/*
“绑定监听器”的监听器创建原理如下伪代码所示
伪代码是在编译时运行的。
*/
button.setOnClickListener(new OnClickListener() {
    
    
	public void onClick(View view) {
    
    
		if(tester != null) {
    
    
			tester.testLongClick(view, "你好");
		}});

expressão ternária

Se precisar usar uma expressão com um predicado (por exemplo, uma expressão ternária), você poderá usar o tipo de valor de retorno que corresponde ao ouvinte como a expressão, como void para o atributo onCLick e Boolean para o atributo onLongClick.

    android:onClick="@{(view)->view.isEnabled()?activity.showSign(view, user):void}"
    android:onLongClick="@{(v)->v.isEnabled()?activity.showSign(user):false}"

Encadernação de páginas secundárias

Chamamos a página referenciada diretamente por Atividade/Fragmento de página de primeiro nível, e a página referenciada pelo rótulo na página de primeiro nível é chamada de página de segundo nível.

Como passar variáveis ​​de layout da página de primeiro nível para a página de segundo nível?

Depois que uma variável de layout é definida no layout de primeiro nível , a variável pode não apenas ser recebida e usada no layout de primeiro nível, mas também se tornar um atributo do booknamespace . O objetivo deste atributo é passar variáveis ​​de layout para o layout secundário.xmlns:app
book

//一级页面
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
	<data>
		<variable
			name = "book"
			type = "xxx.xxx.Book"/>
	</data>

	<LinearLayout
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_height="match_parent">

		<include
			layout="@layout/layout_content"
			app:book="@{book}">
	</LinearLayout>
</layout>

//二级页面
/**
在二级页面layout_content中,需要定义一个与一级页面相同的布局变量,
用来接收传递过来的数据。收到book变量后即可使用该变量了。
*/
<layout xmlns:android="http://schemas.android.com/apk/res/android">
	<data>
		<variable
			name = "book"
			type = "xxx.xxx.Book"/>
	</data>

	<TextView
		……
		android:text="@{book.name}"/>
</layout>

Adaptador de ligação

Binding Adapter (BindingAdapter) é converter a expressão de atributo no layout na chamada de método correspondente para definir o valor .
O chamado valor de configuração é dividido em dois tipos:
①Definir o valor do atributo, como chamar o método setText()
②Definir o ouvinte de evento, como chamar o método setOnClickListener().
Ele também permite que você personalize o método de chamada para definir o valor e forneça sua própria lógica de ligação.

BindingAdapter da biblioteca DataBinding

Muitas classes XXXBindingAdapter são fornecidas na biblioteca DataBinding, que permite que controles nativos do Android suportem expressões de atributos.

//DataBinding库下ViewBindingAdapter的部分源码
public class ViewBindingAdapter {
    
    

	@BindingAdapter({
    
    "android:padding"})
	public static void setPadding(View view, float paddingFloat) {
    
    
		final int padding = pixelsToDimensionPixelSize(paddingFloat);
		view.setPadding(padding, padding, padding, padding);
	}
}

Acho que você gosta

Origin blog.csdn.net/jiejingguo/article/details/118567220
Recomendado
Clasificación