尝试在 activity_main 以外的另一个布局文件夹中更改 ImageButton 的 src

Trying to Change src of an ImageButton in another layout folder other than activity_main

总而言之,我正在尝试从 MainActivity 更改 dialog_colors.xml 文件中 ImageButtons 的 src。但是无论我做什么我都无法改变它。我在 activity_main.xml 中使用 ImageButtons 尝试了相同的代码,但它不适用于 dialog_colors.xml 文件中的按钮。

activity_main.xlm

<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<include
    android:id="@+id/dialog_colors"
    layout="@layout/dialog_colors"/> ...

dialog_colors.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<LinearLayout
    android:id="@+id/ll_paint_colors"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal">

    <ImageButton
        android:id="@+id/red"
        android:layout_width="40sp"
        android:layout_height="40sp"
        android:src="@drawable/pallet_normal"
        android:background="@color/Red"
        android:layout_margin="1sp"
        android:tag="redTag"
        android:clickable="true"
        android:onClick="selectColor"

        />...

MainActivity.kt

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

    colorDialog=findViewById<LinearLayout>(R.id.dialog_colors)
    firstRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors)
    secondRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors2)
    drawingView=findViewById<DrawingView>(R.id.drawingView)

    pressedColor=secondRowColors[0] as ImageButton
    pressedColor!!.setImageResource(R.drawable.pallet_pressed)

}...

我也对 TextViews 等进行了同样的尝试。似乎我无法更改 dialog_colors.xml 文件中的任何内容。

不要对 firstRows、secondRows 等感到困惑,有很多 ImageButtons,它对其中任何一个都不起作用。

我找到了在 MainActivity.ktactivity_main.xmlcontent_main.xml 中定义属性的解决方案(包括布局)。这里的关键词是DataBinding。该项目是完全可重现的,我首先提供 Kotlin,最后提供 JAVA 文件。


KOTLIN:

要启用 DataBinding,您需要转到 build.gradle(Module) 并添加以下代码:

//...
dataBinding{
        enabled true
    }
//...

您将名为 DrawableContainer 的容器定义为 Kotlin class。在那里你定义了一个名为 customDrawable.

Drawable

因此DrawableContainer.kt:

import android.graphics.drawable.Drawable

data class DrawableContainer(val customDrawable: Drawable)

现在我们将定义我们的 MainActivity.kt,它将绑定我们选择的 Drawable 并将其传递给我们的容器 (DrawableContainer)。

我们的MainActivity.kt:

import android.app.Activity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.imagebuttonexperiment.databinding.ActivityMainBinding

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        val binding: ActivityMainBinding = DataBindingUtil.setContentView(
            this, R.layout.activity_main)
        binding.drawable = DrawableContainer(resources.getDrawable(R.drawable.my_image))

    }
}

缺少的部分是我们的 XML 文件。下面的代码显示了我们的 content_main.xml。它包含一个 variable(在 <data> 中)我们将定义命名为 drawabletype 指导我们的 DrawableContainer。所以这是我们的容器和我们将 <include 的布局之间的第一座桥梁。在 ImageButton 中,您可以看到,作为 android:src,我们将 variable 引用到容器中的 Drawable。这就是为什么 android:src="@{drawable.customDrawable}".

因此content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <data>
        <variable
            name="drawable"
            type="com.example.imagebuttonexperiment.DrawableContainer" />
    </data>

    <ImageButton
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_margin="10dp"
        android:src="@{drawable.customDrawable}"/>
</layout>

现在重要的是建造我们的第二座桥。然而,我们有 DrawableContainer -> content_main。这将是桥梁 content_main -> MainActivity。因此,我们再次定义了 <data/>variable。正如您在 <include 中所看到的,我们 bind:drawableXML 两个文件中的 variable 完全相同。 我们的拼图中缺少的部分是 activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:bind="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <data>
        <variable
            name="drawable"
            type="com.example.imagebuttonexperiment.DrawableContainer" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <include
            android:id="@+id/include_content"
            layout="@layout/content_main"
            bind:drawable = "@{drawable}"/>
    </LinearLayout>
</layout>

结果:

最终结果是 MainActivity 中的一个 ImageButton 被另一个 Layout 包含。但是 Drawable 是从 MainActivity 中选择的,并传递了一个 Container 以显示在包含的 Layout 中。是不是魔法!? ;)


JAVA:

我会遵守诺言,同时为您提供 JAVA 版本。 XML文件和gradle一样,只需要用MainActivity.java代替MainActivity.ktDrawableContainer.java代替DrawableContainer.kt ].

这里也是绿色的,DrawableContainer.java:

import android.graphics.drawable.Drawable;

public class DrawableContainer {

    public final Drawable customDrawable;

    public DrawableContainer(Drawable customDrawable) {
        this.customDrawable = customDrawable;
    }
}

当然还有我们的 MainActivity.java:

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import android.annotation.SuppressLint;
import android.graphics.drawable.Drawable;
import android.os.Bundle;

import com.example.imagebuttonexperiment.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityMainBinding mainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        mainBinding.setDrawable(new DrawableContainer(getDrawable(R.drawable.my_image)));
    }
}

下载项目:

此外,我为项目提供了 JAVAKotlin 类。你只需要评论你不想要的2类灰的内容即可。例如,如果你想使用 Kotlin,灰色 .java 个文件的内容。

Github Project


文档和教程:

@DEX7RA 注意:与 DEX7RA 解决方案相关的问题。不是解决方案的答案。 现在我收到这些错误:enter image description here

我与你的代码唯一的区别是 我添加了这个 intead 因为我认为我的版本不接受你的:

buildFeatures{
    dataBinding = true
}

我的activitymain.xml和你举的例子相比是这样的:

<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">

<data>
    <variable
        name="drawable"
        type="com.example.drawingapp.DrawableContainer2" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <include
        android:id="@+id/include_content"
        layout="@layout/dialog_colors"
        bind:drawable = "@{drawable}"/>...

注意:这在某种程度上解决了我的问题: 我试过这个:

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

    colorDialog2=Dialog(this)
    colorDialog2.setContentView(R.layout.dialog_colors)
    colorDialog2.setTitle("Colors")

    firstRowColors=colorDialog2.findViewById<LinearLayout>(R.id.ll_paint_colors)
    secondRowColors=colorDialog2.findViewById<LinearLayout>(R.id.ll_paint_colors2)
    drawingView=findViewById<DrawingView>(R.id.drawingView)

    pressedColor= secondRowColors[0] as ImageButton
    pressedColor!!.setImageResource(R.drawable.pallet_pressed)

}

而不是 Main.Activity

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

colorDialog=findViewById<LinearLayout>(R.id.dialog_colors)
firstRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors)
secondRowColors=colorDialog.findViewById<LinearLayout>(R.id.ll_paint_colors2)
drawingView=findViewById<DrawingView>(R.id.drawingView)

pressedColor=secondRowColors[0] as ImageButton
pressedColor!!.setImageResource(R.drawable.pallet_pressed)}

它奏效了,我设法根据需要更改了 src。 (只是这个改变没有做其他人提供的改变)但是,我什至不确定这是否是一个好的做法。它确实可以作为快速修复。 稍后我会仔细研究 DEX7RA 的答案。