简体   繁体   中英

Adding clickable views dynamically to ScrollView

I'm a newbie to Android development, so apologies if the answers seem obvious to others...

I want to create a task tracker app for my org, where the set of tasks are usually about the same. Here's a mockup: Project Progress Mockup

The mockup shows generic task names, but the real one will have different task names and more of them.

I need some help sorting out the layout design. Conceptually, this is pretty straightforward, but the implementation in Android turns out not to be so straightforward...

I thought I should create a "Task Item" class which contains 3 views: a text view for the task name, a progress bar & another text view for the percentage. Then I wanted to create an array of these Task Items.

Setting all this up in XML is not so bad, but I need it to be dynamic, as it will not always be the same list. Also, using XML is kinda brute force, as I would need to have unique code for each item in this activity, rather than looping through the list dynamically.

It seems like I need a ScrollView. I saw from another post the following statement:

A ScrollView is a FrameLayout, meaning you should place one child in it containing the entire contents to scroll; this child may itself be a layout manager with a complex hierarchy of objects. A child that is often used is a LinearLayout in a vertical orientation, presenting a vertical array of top-level items that the user can scroll through.

So I understand that I need to add my list of Task Items to something like a LinearLayout, which is embedded in the ScrollView. This I can simply set up in XML, right?

Then, for each Task Item, I need to: - create 2 TextViews - set the text to the task name & percentage, respectively - set the font, font size, text color, etc. - set the TextView positions - create a Progress Bar - set the Progress Bar position & percentage

None of this is trivial. So I wonder if it would be easier to set up an XML layout for a single task item & then somehow load() the XML layout. Hopefully from there I could simply set the text & Progress Bar percentage. Would this work, or am I going about this wrong? Also, how would I set up the XML for this? Do I add an activity to my project, or just another XML file?

Finally, I need the task name to be clickable, so I can capture the click & open a new activity showing the subtasks for a task & allowing the user to change the status. Therefore the task name TextView needs to have an ID. Should I make the task names Buttons rather than TextViews? How can I set the ID dynamically? I see that there is a setId(int id) method for Views. But how do I know what integer to use? Android reference View.html states:

View IDs need not be unique throughout the tree, but it is good practice to ensure that they are at least unique within the part of the tree you are searching.

How do I ensure that these IDs are unique?

In the XML file, IDs are not numbers, but rather text, like:

android:id="@+id/my_button"

And this is referenced in the code like this:

Button myButton = findViewById(R.id.my_button);

But how do I create & use unique numeric IDs in order to capture click events on these task names?

Thanks for any pointers you can give!

New information & questions...

I have the basic functionality working, but a couple things aren't quite right:

  1. If you look at my updated mockup, Updated Project Progress Mockup , I want the area highlighted in green to scroll, while the rest stays in place. However, the heading at the top & the button at the bottom scroll off the screen and won't come back. Not sure what I did wrong.

My layout xml looks like this:

<android.support.constraint.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:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorBG"
tools:ignore="LabelFor"
tools:context="com.myorg.myapp.ProjSummary">

<TextView
    android:id="@+id/txtSumm"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/summ"
    android:textAppearance="@style/TextAppearance.AppCompat"
    android:textColor="@color/colorPrimaryDark"
    android:textSize="18sp"
    app:layout_constraintTop_toTopOf="parent"
    android:layout_marginTop="8dp"
    app:layout_constraintBottom_toTopOf="@+id/txtProj"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

<TextView
    android:id="@+id/txtProj"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/proj"
    android:textAppearance="@style/TextAppearance.AppCompat"
    android:textColor="@color/colorPrimaryDark"
    app:layout_constraintTop_toBottomOf="@+id/txtSumm"
    android:layout_marginTop="8dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/edtProj"/>

<EditText
    android:id="@+id/edtProj"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="textPersonName"
    android:paddingTop="5dp"
    android:paddingBottom="0dp"
    android:paddingStart="0dp"
    android:paddingEnd="0dp"
    android:textColor="@color/colorPrimaryDark"
    android:textSize="14sp"
    app:layout_constraintTop_toBottomOf="@+id/txtSumm"
    app:layout_constraintLeft_toRightOf="@+id/txtProj"
    app:layout_constraintRight_toRightOf="parent"/>

<ImageView
    android:id="@+id/imgLogo"
    android:layout_width="120dp"
    android:layout_height="48dp"
    android:scaleType="fitXY"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/btnSend"
    app:srcCompat="@mipmap/my_logo"
    android:contentDescription="@string/org_logo"/>

<Button
    android:id="@+id/btnSend"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:backgroundTint="@color/colorSecondaryDark"
    android:text="@string/send"
    android:textColor="@color/colorButtonText"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toRightOf="@+id/imgLogo"
    app:layout_constraintRight_toRightOf="parent"/>

<android.support.v7.widget.RecyclerView
    android:id="@+id/rvTaskList"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@+id/txtProj"
    app:layout_constraintBottom_toTopOf="@+id/imgLogo"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"/>

  1. My last task item never is displayed. (ie if I have 10 task items, only the first 9 are displayed.) In my activity class, I have an ArrayList for the summary list of task items:

     private ArrayList _alSummaries; 

And in my RecyclerView.Adapter class, I have the following method:

    @Override
public int getItemCount() { return _alSummaries.size(); }

Anywhere else I should look?

Thanks!

Further update:

  1. in my layout I had...

android:layout_height="wrap_content"

Rather than wrap_content, it should have been "0dp". Seems like a bug in Android, actually - if I say wrap_content, that should never cause the view to become larger than the space available to it (as set by the constraints).

  1. Problem solved - not a problem with the interface, but with the code that loaded my data into the app.

So I wonder if it would be easier to set up an XML layout for a single task item & then somehow load() the XML layout. Hopefully from there I could simply set the text & Progress Bar percentage.

This is what a Recycler View adapter does. You have an xml layout containing the three simple views: a text, the bar and another text.

Now in your code (in the adapter), you inflate each row and set the text and progress bar individually.

Should I make the task names Buttons rather than TextViews? How can I set the ID dynamically?

You do not need to do that. You can just assign custom onClick listeners which do what you want in the adapter code.

For a beginner, the setup is definitely not trivial, but once you get the hang of it, you will find it to be a very valuable tool.

Look here for the official tutorial: https://developer.android.com/training/material/lists-cards.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM