mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
feat: add basic layout for attribute value editor
This commit is contained in:
@@ -289,7 +289,7 @@
|
||||
<string name="msg_file_tree">File tree</string>
|
||||
<string name="hint_color_resource">Color resource</string>
|
||||
<string name="title_color_picker">Color picker</string>
|
||||
<string name="hint_string_value">String value</string>
|
||||
<string name="hint_attr_value">Attribute value</string>
|
||||
<string name="hint_string_resource">String resource</string>
|
||||
<string name="hint_resource_reference">Any resource reference</string>
|
||||
<string name="msg_code_actions">Actions</string>
|
||||
|
||||
Binary file not shown.
@@ -19,6 +19,7 @@ package com.itsaky.androidide.uidesigner
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.core.view.GravityCompat
|
||||
@@ -26,6 +27,9 @@ import com.itsaky.androidide.app.BaseIDEActivity
|
||||
import com.itsaky.androidide.uidesigner.databinding.ActivityUiDesignerBinding
|
||||
import com.itsaky.androidide.uidesigner.fragments.DesignerWorkspaceFragment
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VALUE_EDITOR
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VIEW_INFO
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
|
||||
/**
|
||||
* The UI Designer activity allows the user to design XML layouts with a drag-n-drop interface.
|
||||
@@ -34,6 +38,7 @@ import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
*/
|
||||
class UIDesignerActivity : BaseIDEActivity() {
|
||||
|
||||
private val log = ILogger.newInstance("UIDesignerActivity")
|
||||
private var binding: ActivityUiDesignerBinding? = null
|
||||
private val workspace: DesignerWorkspaceFragment?
|
||||
get() = this.binding?.workspace?.getFragment()
|
||||
|
||||
+5
-1
@@ -31,7 +31,7 @@ import com.itsaky.androidide.uidesigner.databinding.LayoutViewattrItemBinding
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class ViewAttrListAdapter(attributes: List<IAttribute>) : RecyclerView.Adapter<VH>() {
|
||||
class ViewAttrListAdapter(attributes: List<IAttribute>, private val onClick: (IAttribute) -> Unit) : RecyclerView.Adapter<VH>() {
|
||||
|
||||
private val attributes = attributes.sortedBy { it.name }
|
||||
|
||||
@@ -52,5 +52,9 @@ class ViewAttrListAdapter(attributes: List<IAttribute>) : RecyclerView.Adapter<V
|
||||
|
||||
binding.attrName.text = "${attr.namespace.prefix}:${attr.name}"
|
||||
binding.attrValue.text = attr.value
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
onClick(attr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.uidesigner.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutAttrValueEditorBinding
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoHeaderBinding
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
|
||||
/**
|
||||
* Fragment to allow the user to edit the value of the selected fragment.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class AttrValueEditorFragment : Fragment() {
|
||||
|
||||
private var header: LayoutViewInfoHeaderBinding? = null
|
||||
private val viewModel by viewModels<WorkspaceViewModel>(ownerProducer = { requireActivity() })
|
||||
private var binding: LayoutAttrValueEditorBinding? = null
|
||||
set(value) {
|
||||
if (value == null) {
|
||||
field = null
|
||||
header = null
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
header = LayoutViewInfoHeaderBinding.bind(value.root)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
this.binding = LayoutAttrValueEditorBinding.inflate(inflater, container, false)
|
||||
return this.binding!!.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
viewModel._selectedAttr.observe(viewLifecycleOwner) { showAttrInfo() }
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun showAttrInfo() {
|
||||
val binding = this.binding ?: return
|
||||
val header = this.header ?: return
|
||||
val attr = this.viewModel.selectedAttr ?: return
|
||||
|
||||
header.name.text = "${attr.namespace.prefix}:${attr.name}"
|
||||
header.desc.text = attr.namespace.uri
|
||||
binding.attrValue.editText?.setText(attr.value)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
this.binding = null
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -42,14 +42,14 @@ import com.itsaky.androidide.uidesigner.UIDesignerActivity
|
||||
import com.itsaky.androidide.uidesigner.databinding.FragmentDesignerWorkspaceBinding
|
||||
import com.itsaky.androidide.uidesigner.drag.WidgetDragListener
|
||||
import com.itsaky.androidide.uidesigner.drag.WidgetTouchListener
|
||||
import com.itsaky.androidide.uidesigner.fragments.ViewInfoDialogFragment.Companion.TAG
|
||||
import com.itsaky.androidide.uidesigner.fragments.ViewInfoFragment.Companion.TAG
|
||||
import com.itsaky.androidide.uidesigner.models.PlaceholderView
|
||||
import com.itsaky.androidide.uidesigner.models.UiView
|
||||
import com.itsaky.androidide.uidesigner.models.UiViewGroup
|
||||
import com.itsaky.androidide.uidesigner.utils.bgDesignerView
|
||||
import com.itsaky.androidide.uidesigner.utils.layeredForeground
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.FLIPPER_SCREEN_WORKSPACE
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_WORKSPACE
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import java.io.File
|
||||
|
||||
@@ -68,7 +68,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
UiViewGroup(LayoutFile(File(""), ""), LinearLayout::class.qualifiedName!!, binding!!.workspace)
|
||||
}
|
||||
|
||||
private val viewInfo by lazy { ViewInfoDialogFragment() }
|
||||
private val viewInfo by lazy { ViewInfoSheet() }
|
||||
|
||||
private val placeholder by lazy {
|
||||
val view =
|
||||
@@ -89,7 +89,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
setupView(view as UiView)
|
||||
|
||||
if (workspaceView.childCount == 0) {
|
||||
viewModel.flipperScreen = FLIPPER_SCREEN_WORKSPACE
|
||||
viewModel.workspaceFlipperScreen = SCREEN_WORKSPACE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel._flipperScreen.observe(viewLifecycleOwner) { binding?.flipper?.displayedChild = it }
|
||||
viewModel._workspaceScreen.observe(viewLifecycleOwner) { binding?.flipper?.displayedChild = it }
|
||||
|
||||
viewModel._errText.observe(viewLifecycleOwner) { binding?.errText?.text = it }
|
||||
|
||||
@@ -172,7 +172,7 @@ class DesignerWorkspaceFragment : BaseFragment() {
|
||||
private fun setupView(view: IView) {
|
||||
view.view.setOnTouchListener(
|
||||
WidgetTouchListener(view, requireContext()) {
|
||||
viewInfo.view = it
|
||||
viewModel.view = it
|
||||
viewInfo.show(childFragmentManager, TAG)
|
||||
true
|
||||
}
|
||||
|
||||
+27
-17
@@ -21,31 +21,38 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.itsaky.androidide.uidesigner.adapters.ViewAttrListAdapter
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoBinding
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoHeaderBinding
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VALUE_EDITOR
|
||||
|
||||
/**
|
||||
* A [BottomSheetDialogFragment] which shows information about a clicked view.
|
||||
*
|
||||
* @author Akash Yadav
|
||||
*/
|
||||
class ViewInfoDialogFragment : BottomSheetDialogFragment() {
|
||||
class ViewInfoFragment : Fragment() {
|
||||
|
||||
private val viewModel by viewModels<WorkspaceViewModel>(ownerProducer = { requireActivity() })
|
||||
private var binding: LayoutViewInfoBinding? = null
|
||||
|
||||
var view: IView? = null
|
||||
set(value) {
|
||||
field = value
|
||||
if (isShowing) {
|
||||
showViewInfo()
|
||||
if (value == null) {
|
||||
field = null
|
||||
header = null
|
||||
return
|
||||
}
|
||||
|
||||
field = value
|
||||
header = LayoutViewInfoHeaderBinding.bind(value.root)
|
||||
}
|
||||
|
||||
val isShowing: Boolean
|
||||
get() = dialog?.isShowing ?: false
|
||||
|
||||
private var header: LayoutViewInfoHeaderBinding? = null
|
||||
|
||||
companion object {
|
||||
const val TAG = "ide.uidesigner.viewinfo"
|
||||
}
|
||||
@@ -61,7 +68,7 @@ class ViewInfoDialogFragment : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
if (this.view != null) {
|
||||
viewModel._view.observe(viewLifecycleOwner) {
|
||||
showViewInfo()
|
||||
}
|
||||
}
|
||||
@@ -73,15 +80,18 @@ class ViewInfoDialogFragment : BottomSheetDialogFragment() {
|
||||
|
||||
private fun showViewInfo() {
|
||||
val binding = this.binding ?: return
|
||||
val view = this.view ?: return
|
||||
val header = this.header ?: return
|
||||
val view = this.viewModel.view ?: return
|
||||
|
||||
header.name.text = view.simpleName
|
||||
header.desc.text = view.name
|
||||
binding.attrList.adapter = ViewAttrListAdapter(view.attributes) {
|
||||
viewModel.selectedAttr = it
|
||||
viewModel.viewInfoScreen = SCREEN_VALUE_EDITOR
|
||||
}
|
||||
|
||||
binding.viewName.text = view.simpleName
|
||||
binding.viewInfo.text = view.name
|
||||
binding.attrList.adapter = ViewAttrListAdapter(view.attributes)
|
||||
|
||||
binding.btnDelete.setOnClickListener {
|
||||
view.removeFromParent()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.itsaky.androidide.uidesigner.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.ComponentDialog
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.transition.TransitionManager.beginDelayedTransition
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.itsaky.androidide.uidesigner.databinding.LayoutViewInfoSheetBinding
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VALUE_EDITOR
|
||||
import com.itsaky.androidide.uidesigner.viewmodel.WorkspaceViewModel.Companion.SCREEN_VIEW_INFO
|
||||
|
||||
/** @author Akash Yadav */
|
||||
class ViewInfoSheet : BottomSheetDialogFragment() {
|
||||
private var binding: LayoutViewInfoSheetBinding? = null
|
||||
private val viewModel by viewModels<WorkspaceViewModel>(ownerProducer = { requireActivity() })
|
||||
|
||||
val isShowing: Boolean
|
||||
get() = dialog?.isShowing ?: false
|
||||
|
||||
private val viewInfoBackPressedCallback =
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (viewModel.viewInfoScreen == SCREEN_VALUE_EDITOR) {
|
||||
viewModel.viewInfoScreen = SCREEN_VIEW_INFO
|
||||
isEnabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
this.binding = LayoutViewInfoSheetBinding.inflate(inflater, container, false)
|
||||
return this.binding!!.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel._viewInfoScreen.observe(viewLifecycleOwner) {
|
||||
binding?.apply {
|
||||
val prev = flipper.displayedChild
|
||||
beginDelayedTransition(root, MaterialSharedAxis(MaterialSharedAxis.X, prev < it))
|
||||
flipper.displayedChild = it
|
||||
}
|
||||
this.viewInfoBackPressedCallback.isEnabled = it == SCREEN_VALUE_EDITOR
|
||||
}
|
||||
|
||||
viewModel._view.observe(viewLifecycleOwner) { viewModel.viewInfoScreen = SCREEN_VIEW_INFO }
|
||||
|
||||
(requireDialog() as ComponentDialog)
|
||||
.onBackPressedDispatcher
|
||||
.addCallback(viewLifecycleOwner, viewInfoBackPressedCallback)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
this.binding = null
|
||||
}
|
||||
}
|
||||
+37
-14
@@ -17,45 +17,68 @@
|
||||
|
||||
package com.itsaky.androidide.uidesigner.viewmodel
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.itsaky.androidide.inflater.IAttribute
|
||||
import com.itsaky.androidide.inflater.IView
|
||||
import java.io.File
|
||||
|
||||
class WorkspaceViewModel : ViewModel() {
|
||||
internal val _drawerOpened = MutableLiveData(false)
|
||||
internal val _errText = MutableLiveData("")
|
||||
internal val _flipperScreen = MutableLiveData(0)
|
||||
internal val _workspaceScreen = MutableLiveData(SCREEN_WORKSPACE)
|
||||
internal val _viewInfoScreen = MutableLiveData(SCREEN_VIEW_INFO)
|
||||
internal val _view = MutableLiveData<IView>(null)
|
||||
internal val _selectedAttr = MutableLiveData<IAttribute>(null)
|
||||
private val _file = MutableLiveData<File>()
|
||||
|
||||
|
||||
companion object {
|
||||
const val FLIPPER_SCREEN_WORKSPACE = 0
|
||||
const val FLIPPER_SCREEN_ERROR = 1
|
||||
const val SCREEN_WORKSPACE = 0
|
||||
const val SCREEN_ERROR = 1
|
||||
const val SCREEN_VIEW_INFO = 0
|
||||
const val SCREEN_VALUE_EDITOR = 1
|
||||
}
|
||||
|
||||
|
||||
var file: File
|
||||
get() = _file.value!!
|
||||
set(value) {
|
||||
_file.value = value
|
||||
}
|
||||
|
||||
var drawerOpened : Boolean
|
||||
|
||||
var drawerOpened: Boolean
|
||||
get() = this._drawerOpened.value!!
|
||||
set(value) {
|
||||
this._drawerOpened.value = value
|
||||
}
|
||||
|
||||
|
||||
var errText: String
|
||||
get() = _errText.value ?: ""
|
||||
set(value) {
|
||||
_errText.value = value
|
||||
flipperScreen = FLIPPER_SCREEN_ERROR
|
||||
workspaceFlipperScreen = SCREEN_ERROR
|
||||
}
|
||||
|
||||
var workspaceFlipperScreen: Int
|
||||
get() = _workspaceScreen.value ?: SCREEN_WORKSPACE
|
||||
set(value) {
|
||||
_workspaceScreen.value = value
|
||||
}
|
||||
|
||||
var view: IView?
|
||||
get() = this._view.value
|
||||
set(value) {
|
||||
this._view.value = value
|
||||
}
|
||||
|
||||
var viewInfoScreen: Int
|
||||
get() = _viewInfoScreen.value ?: SCREEN_VIEW_INFO
|
||||
set(value) {
|
||||
_viewInfoScreen.value = value
|
||||
}
|
||||
|
||||
var flipperScreen: Int
|
||||
get() = _flipperScreen.value ?: FLIPPER_SCREEN_WORKSPACE
|
||||
var selectedAttr: IAttribute?
|
||||
get() = this._selectedAttr.value
|
||||
set(value) {
|
||||
_flipperScreen.value = value
|
||||
this._selectedAttr.value = value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ AndroidIDE is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<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="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<include layout="@layout/layout_view_info_header" />
|
||||
|
||||
<include
|
||||
android:id="@+id/_title_attr_divider"
|
||||
layout="@layout/layout_divider_horizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/desc" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/attr_value"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:hint="@string/hint_attr_value"
|
||||
android:theme="@style/AppTheme.TextInputLayout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/comment"
|
||||
app:layout_constraintTop_toTopOf="@id/comment">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="1"
|
||||
tools:text="match_parent" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/comment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@id/attr_value"
|
||||
app:layout_constraintStart_toStartOf="@id/name"
|
||||
app:layout_constraintTop_toBottomOf="@id/_title_attr_divider"
|
||||
tools:text="Specifies the basic height of the view. This is a required attribute for any view inside of a containing layout manager. Its value may be a dimension (such as "12dip") for a constant height or one of the special constants." />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -34,14 +34,6 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/err_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
tools:text="This is an error." />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/workspace"
|
||||
android:layout_width="match_parent"
|
||||
@@ -51,6 +43,14 @@
|
||||
android:backgroundTintMode="src_atop"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/err_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
tools:text="This is an error." />
|
||||
|
||||
</ViewFlipper>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ AndroidIDE is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<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="wrap_content"
|
||||
android:background="@color/content_background"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<include layout="@layout/layout_view_info_header" />
|
||||
|
||||
<include
|
||||
android:id="@+id/_title_attr_divider"
|
||||
layout="@layout/layout_divider_horizontal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/desc" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/comment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/name"
|
||||
app:layout_constraintTop_toBottomOf="@id/_title_attr_divider"
|
||||
tools:text="Specifies the basic height of the view. This is a required attribute for any view inside of a containing layout manager. Its value may be a dimension (such as "12dip") for a constant height or one of the special constants." />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/attr_value"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:hint="@string/hint_attr_value"
|
||||
android:theme="@style/AppTheme.TextInputLayout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/comment">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -20,29 +20,11 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/content_background"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/view_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="TextView" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/view_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintStart_toStartOf="@id/view_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/view_name"
|
||||
tools:text="android.widget.TextView" />
|
||||
<include layout="@layout/layout_view_info_header" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_delete"
|
||||
@@ -54,9 +36,9 @@
|
||||
android:tooltipText="@string/title_viewaction_delete"
|
||||
app:icon="@drawable/ic_delete"
|
||||
app:iconTint="@color/secondaryIconColor"
|
||||
app:layout_constraintBottom_toBottomOf="@id/view_info"
|
||||
app:layout_constraintBottom_toBottomOf="@id/desc"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/view_name" />
|
||||
app:layout_constraintTop_toTopOf="@id/name" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_add"
|
||||
@@ -79,7 +61,7 @@
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/view_info" />
|
||||
app:layout_constraintTop_toBottomOf="@id/desc" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/attr_list"
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ AndroidIDE is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<merge 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"
|
||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="TextView" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintStart_toStartOf="@id/name"
|
||||
app:layout_constraintTop_toBottomOf="@id/name"
|
||||
tools:text="android.widget.TextView" />
|
||||
|
||||
</merge>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ AndroidIDE is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<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="wrap_content">
|
||||
|
||||
<ViewFlipper
|
||||
android:id="@+id/flipper"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/view_info"
|
||||
android:name="com.itsaky.androidide.uidesigner.fragments.ViewInfoFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:layout="@layout/layout_view_info" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/attr_editor"
|
||||
android:name="com.itsaky.androidide.uidesigner.fragments.AttrValueEditorFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:layout="@layout/layout_attr_value_editor" />
|
||||
|
||||
</ViewFlipper>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Reference in New Issue
Block a user