German Hintergrundfarbe bei ScrollView

Wosl

Member
Hallo!

Das ist wahrscheinlich eine "Brett vor dem Kopf" Frage.

Ich möchte in einer Scrollview mehrere Spalten zeigen (im Beispiel 4). Die Zellen werden mit Text als Label Views gefüllt außer der 3. Spalte. Hier möchte ich transparente Bitmaps zeigen und benutze Imageview. Die Zeilen sollen im Wechsel eingefärbt werden (TableColor1 und 2), was bei den Label Views funktioniert, aber nicht bei den Bitmaps. Hier erscheint immer die Table Color (hier Magenta).
Was muss ich machen, um auch in Spalte 3 den transparenten Hintergrund der Bitmap wie in den anderen Spalten zu färben?

Grüße
Wosl

Beispiel Code:
Scrollview example:
Sub FillSV
    Private NumberofRows As Int = 100, NumberofColumns As Int = 4, iBackColor As Int
    Private iColWidth(NumberofColumns) As String = Array As String("15.0", "50.0", "15.0", "20.0")
    Private l As Label,    ImageView1 As ImageView, scvMain As ScrollView, Table As Panel
    Private TableFontSize As Float = 16, TableRowHeight As Int = 40dip
    Private TableColor1 As Int = Colors.RGB(184,204,228)
    Private TableColor2 As Int = Colors.RGB(220,230,241)
    Private iRow As Int, iCol As Int
    Private ColumnWidth As Int, ColumnWidthSum As Int

    scvMain.Initialize(0)
    Activity.AddView(scvMain,0,0,100%x,100%y)
    Table = scvMain.Panel
    Table.Color = Colors.Magenta
    Table.Height = NumberofRows * TableRowHeight
    
    For iRow = 0 To NumberofRows - 1
        ColumnWidthSum = 0
        For iCol = 0 To NumberofColumns - 1
            ColumnWidth= scvMain.Width * iColWidth(iCol)/100.0
            If iRow Mod 2 == 0 Then
                iBackColor = TableColor1
            Else
                iBackColor = TableColor2
            End If
            If iCol <> 2 Then
                l.Initialize("")
                l.Text = "XYZ"
                l.TextColor = Colors.Black
                l.TextSize = TableFontSize
                l.Color = iBackColor
                l.Gravity = Gravity.CENTER_VERTICAL + Gravity.CENTER_HORIZONTAL
                Table.AddView(l, ColumnWidthSum, TableRowHeight * iRow, ColumnWidth, TableRowHeight)
            Else           
                Private Bitmap1 As Bitmap = LoadBitmapResize(File.DirAssets, "Pfeiloben.png", 0.5 * ColumnWidth, 0.5 * ColumnWidth, True)
                ImageView1.Initialize("")
''                ImageView1.Color = Colors.Transparent
''                ImageView1.Color = iBackColor
                ImageView1.Bitmap = Bitmap1
                ImageView1.Width = ColumnWidth
                ImageView1.Height = TableRowHeight
                ImageView1.Gravity = Gravity.CENTER_VERTICAL + Gravity.CENTER_HORIZONTAL
                Table.AddView(ImageView1,ColumnWidthSum, TableRowHeight * iRow, ColumnWidth, TableRowHeight)
            End If           
            ColumnWidthSum = ColumnWidthSum + ColumnWidth
        Next
    Next
End Sub
 

Attachments

  • CustomScrollViewMyVersion3.zip
    43.2 KB · Views: 133

MicroDrie

Well-Known Member
Licensed User
Lieber Wosl,

Zunächst dachte ich, die Manifestdatei sei sehr veraltet. In B4A Version 10.70 habe ich eine mögliche Lösung mit B4APages gemacht.
Basis für die Lösung ist eine Standard-B4XTable. Zunächst wird die Spalte mit einem leeren Text gefüllt. Platzieren Sie dann eine Ansicht mit dem transparenten Bild darüber.
Durch Markieren der Ansicht können wir das Tag verwenden, wenn das Bild berührt wird.
Sie können jede Textspalte in aufsteigender oder absteigender Reihenfolge sortieren, indem Sie die Überschrift berühren.
Die Quelle der Tabelle kann alles sein, was in eine "Liste" konvertiert wurde. Auf der Website gibt es viel über B4XTable zu finden.

1621949728761.png


B4A source:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    
    Private B4XTable1 As B4XTable
    Private XSelections As B4XTableSelections
    
    Private B4XComboBox1 As B4XComboBox
    
    Private PfeilColumn As B4XTableColumn
    
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    'load the layout to Root
    Root.LoadLayout("Table")
    FillSV

End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Sub FillSV
    Private NumberofRows As Int = 100
    Private TableRowHeight As Int = 50dip
    B4XTable1.RowHeight = TableRowHeight
    
'    --- Define the rowcolors ---
    Private TableColor1 As Int = Colors.RGB(184,204,228)
    Private TableColor2 As Int = Colors.RGB(220,230,241)
    
    B4XTable1.AddColumn("Text1", B4XTable1.COLUMN_TYPE_NUMBERS).Width = 50dip
    B4XTable1.AddColumn("Text2", B4XTable1.COLUMN_TYPE_TEXT)
    PfeilColumn = B4XTable1.AddColumn("Pfeil", B4XTable1.COLUMN_TYPE_TEXT)
    PfeilColumn.Width = 50dip
    PfeilColumn.Searchable = False
    PfeilColumn.Sortable = False
    B4XTable1.AddColumn("Text3", B4XTable1.COLUMN_TYPE_TEXT)'.Width = 20dip
    
'    --- Set the rowcolors ---   
    B4XTable1.EvenRowColor = TableColor1
    B4XTable1.OddRowColor = TableColor2
    
    Dim Data As List
    Data.Initialize
    
'    --- Create table content ---
    For iRow = 0 To NumberofRows - 1
        Data.Add(Array(iRow + 1, $"XYZ${iRow + 1}"$, "", $"${iRow + 1}XYZ"$))
    Next
    
'    --- Fill the table ---
    B4XTable1.SetData(Data)
    B4XTable1.MaximumRowsPerPage = 10
    B4XTable1.BuildLayoutsCache(10)
    
'    ---  Skipp header and add an ImageView to each of the flags column cells ---
    For i = 1 To PfeilColumn.CellsLayouts.Size - 1
        Dim pnl As B4XView = PfeilColumn.CellsLayouts.Get(i)
        Dim iv As ImageView
        iv.Initialize("")
        pnl.AddView(iv, 5dip, 5dip, PfeilColumn.Width - 10dip, B4XTable1.RowHeight - 10dip)
    Next

'    MODE_SINGLE_CELL_TEMP - this Is the built-in selection mode. Unlike the other selection modes it disappears automatically.
'    MODE_SINGLE_CELL_PERMANENT - selection of a single cell.
'    MODE_SINGLE_LINE_PERMANENT - selection of a single line.
'    MODE_MULTIPLE_CELLS - selection of multiple cells.
'    MODE_MULTIPLE_LINES - selection of multiple lines
    
    XSelections.Initialize(B4XTable1)
    XSelections.Mode = XSelections.MODE_SINGLE_CELL_PERMANENT
    B4XComboBox1.SetItems(Array("SINGLE_CELL_TEMP", "SINGLE_CELL_PERMANENT", "SINGLE_LINE_PERMANENT", "MULTIPLE_CELLS", "MULTIPLE_LINES"))
    B4XComboBox1.DelayBeforeChangeEvent = 0

    'uncomment if you want selections to be removed automatically when the cell or line are not visible.
'    XSelections.AutoRemoveInvisibleSelections = True
    
    
    
End Sub

Sub B4XTable1_DataUpdated
    For i = 0 To B4XTable1.VisibleRowIds.Size - 1
        Dim RowId As Long = B4XTable1.VisibleRowIds.Get(i)
        Dim pnl As B4XView = PfeilColumn.CellsLayouts.Get(i + 1) '+1 because the first cell is the header
        Dim iv As B4XView = pnl.GetView(1) 'ImageView will be the 2nd child of the panel. The built-in label is the first.
        If RowId > 0 Then
'            Dim row As Map = B4XTable1.GetRow(RowId)
            iv.SetBitmap(xui.LoadBitmapResize(File.DirAssets, "Pfeiloben.png", iv.Width, iv.Height, True))
            iv.Tag = $"Pfeiloben${i + 1}"$
        Else
            'empty row
            iv.SetBitmap(Null)
        End If
    Next
    XSelections.Refresh
End Sub

Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
    Dim RowData As Map = B4XTable1.GetRow(RowId)
    Dim cell As String = RowData.Get(ColumnId)
    Log($"Id: ${ColumnId} RowId ${RowId} Cell: ${ cell}"$)
    
    XSelections.CellClicked(ColumnId, RowId)
    
    If ColumnId = "Pfeil" And cell = "" Then
        Dim pnl As B4XView = PfeilColumn.CellsLayouts.Get(RowId)
        Dim iv As B4XView = pnl.GetView(1)
        Dim TagStr As String = iv.Tag
        Log(TagStr)
        Dim su As ApacheSU
        If su.StartsWith(TagStr,"Pfeiloben") = True Then
            Log($"Found ${TagStr}"$)
            iv.SetBitmap(xui.LoadBitmapResize(File.DirAssets, "Pfeilnieder.png", iv.Width, iv.Height, True))
            iv.Tag = $"Pfeilnieder${RowId}"$
        End If
        If su.StartsWith(TagStr,"Pfeilnieder") = True Then
            Log($"Found ${TagStr}"$)
            iv.SetBitmap(xui.LoadBitmapResize(File.DirAssets, "Pfeiloben.png", iv.Width, iv.Height, True))
            iv.Tag = $"Pfeilnieder${RowId}"$
        End If
        Sleep(200)
        B4XTable1.Refresh
    End If
End Sub

'    --- Change the Sort Direction Arrow Color Based on its Direction ---
Sub B4XTable1_HeaderClicked (ColumnId As String)
    Dim up As Boolean = B4XTable1.lblSort.Text = Chr(0xF0DE)
    B4XTable1.lblSort.Text = ""
    Sleep(50)
    If Not(up) Then
        B4XTable1.lblSort.Text = "D"
        B4XTable1.lblSort.textColor= xui.Color_Red
    Else
        B4XTable1.lblSort.Text = "U"
        B4XTable1.lblSort.textColor= xui.Color_Green
    End If
End Sub


Sub B4XComboBox1_SelectedIndexChanged (Index As Int)
    Dim mode As Int = Index + 1 'implementation detail. You should use the constants instead
    XSelections.Mode = mode
End Sub

Sub btnClear_Click
    XSelections.Clear
End Sub

Sub btnLog_Click
    If XSelections.Mode = XSelections.MODE_SINGLE_CELL_TEMP Then
        Log("Temporary mode. No selection")
        Return
    End If
    Dim LineMode As Boolean = XSelections.Mode = XSelections.MODE_MULTIPLE_LINES Or XSelections.Mode = XSelections.MODE_SINGLE_LINE_PERMANENT
    If XSelections.IsSelected = False Then
        Log("Nothing is selected")
    Else
        Log($"First selected row id: ${XSelections.FirstSelectedRowId}"$)
        If LineMode = False Then Log($"First selected column: ${XSelections.FirstSelectedColumnId}"$)
        Dim sb As StringBuilder
        sb.Initialize
        If LineMode Then
            sb.Append("The following rows are selected:").Append(CRLF)
            For Each rowid As Long In XSelections.SelectedLines.Keys
                sb.Append(rowid).Append(CRLF)
            Next
        Else
            sb.Append("The following cells are selected:").Append(CRLF)
            For Each rowid As Long In XSelections.SelectedLines.Keys
                Dim cols As List = XSelections.SelectedLines.Get(rowid)
                For Each col As String In cols
                    sb.Append("(").Append(rowid).Append(", ").Append(col).Append(")").Append(CRLF)
                Next
            Next
        End If
        Log(sb.ToString)
        xui.MsgboxAsync(sb.ToString, "Selection")
    End If
End Sub
 

Attachments

  • CustomScrollViewMyVersion4.zip
    17 KB · Views: 155

Wosl

Member
Vielen Dank MicroDrie,

diese Lösung ergibt deutlich mehr Flexibilität, z.B. das sortieren einer Spalte in aufsteigender oder absteigender Reihenfolge. Das ist ein Feature, das ich auch schon für meine App überlegt habe. Ich werde mich jetzt mit B4XTable im Detail beschäftigen und deine Vorlage wird mir dabei helfen. Vielen Dank für die Mühe.

Als Feedback, ich habe eine einfache Methode für mein Problem gefunden, die ich kurz zeige. Statt ImageView verwende ich CSBuilder (siehe markierte Zeilen). Die Lösung ist dann
Transparentes Laden von Bitmaps in einem Scroll View:
    For iRow = 0 To NumberofRows - 1
        ColumnWidthSum = 0
        For iCol = 0 To NumberofColumns - 1
            ColumnWidth= scvMain.Width * iColWidth(iCol)/100.0
            If iRow Mod 2 == 0 Then
                iBackColor = TableColor1
            Else
                iBackColor = TableColor2
            End If
            If iCol <> 2 Then
                l.Initialize("")
                l.Text = "XYZ"
                l.TextColor = Colors.Black
                l.TextSize = TableFontSize
                l.Color = iBackColor
                l.Gravity = Gravity.CENTER_VERTICAL + Gravity.CENTER_HORIZONTAL
                Table.AddView(l, ColumnWidthSum + igridWidth, TableRowHeight * iRow + igridWidth, ColumnWidth - 2 * igridWidth, TableRowHeight - 2 * igridWidth)
            Else
                cs.Initialize.Size(30).Typeface(Typeface.MONOSPACE)
                cs.Append("").Image(LoadBitmap(File.DirAssets, "Pfeiloben.png"), 0.4 * ColumnWidth, 0.3 * ColumnWidth, False)
                cs.PopAll
                l.Initialize("")
                l.Text = cs
                l.Color = iBackColor
                l.Gravity = Gravity.CENTER_VERTICAL + Gravity.CENTER_HORIZONTAL
                Table.AddView(l, ColumnWidthSum + igridWidth, TableRowHeight * iRow + igridWidth, ColumnWidth- 2 * igridWidth, TableRowHeight- 2 * igridWidth)           
            End If           
            ColumnWidthSum = ColumnWidthSum + ColumnWidth
        Next
    Next
cs ist als CSBuilder zu vereinbaren (Private cs as CSBuilder). Um die Zelle zu identifizieren, die angeclickt wurde, muss sie noch mit einem Tag versehen werden, der Spalte und Zeile im Click Event liefert (hier im Beispiel nicht gezeigt).

Nochmals Danke für die Mühe. Ich werde mich damit beschäftigen und bestimmt wieder etwas dazulernen.

Viele Grüße
Wosl
 

MicroDrie

Well-Known Member
Licensed User
Ja, du bist nie zu alt, um zu lernen. Es gibt viele Beispiele dafür, was Sie mehr als nur mit B4XTable auf der B4X-Site suchen und sortieren können.

Durch die Entwicklung mit B4XPages können Sie Programme unter B4J auf Ihrem PC entwickeln und testen. Auf diese Weise können Sie die Programmteile in einem gemeinsamen Verzeichnis wiederverwenden und als vorhandene Programmroutinen im anderen Verzeichnis B4A, B4J, B4I und B4R wiederverwenden. Sie platzieren eine bestimmte Software für B4A, B4J, B4I und B4R zwischen der # IF-Anweisung.

Ich habe also das gleiche Menü in B4J und B4A realisiert. Ich arbeite jetzt unter dieser Menülösung, um B4XPages und Klassen wiederzuverwenden (wiederzuverwenden).
 
Top