How to change the position of elements using ConstraintLayout Flow? - android

Few days ago I want to customize a TabLayout like this (RallyTab), which uses Flow and can rearrange the elements according to the clicked icon.
I read its source code, and its function of rearranging elements seems to be achieved by the ConstraintHelper.setReferencedIds(int[] ids) on line 168. But when I try the following code, it does not work:
findViewById(R.id.button).setOnClickListener(v -> {
Flow flow = findViewById(R.id.flow);
int[] ids = new int[] {R.id.image1, R.id.image3, R.id.image2, R.id.image4, R.id.image5};
flow.setReferencedIds(ids);
});
This is layout xml:
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/cl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32dp">
<androidx.constraintlayout.helper.widget.Flow
android:id="#+id/flow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image1, image2, image3, image4, image5"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/image1"
android:layout_width="52dp"
android:layout_height="52dp"
app:srcCompat="#drawable/ic_baseline_exposure_neg_2_24" />
<!-- image2, image3, image4, image5 are the same as image1, only the id and srcCompat are different -->
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Button" />
</LinearLayout>
Even if I copy its source code and layout xml to my project, it still not work. When i clicked on its icon, the position of elements did not change, only the TextView was playing its beautiful animation.
So I realized that the ConstraintHelper.setReferencedIds(int[] ids) method does not change the position of elements (or it will, welcome to correct me :-)), and RallyTab may have called some method in somewhere that I did not notice to rearrange them.
How do I do to change the position of elements like RallyTab? Can anybody point out where I missed? Or what should I do to achieve this function without Flow? Thanks in advance.

Related

Xamarin Android LinearLayout - Problem with 2 RecyclerViews on one page

I'm having issues with the v7.widget.RecyclerView. I have a "post" from the app user, which displays any images they have previously added, as well as any other attachments (documents, videos etc.). There is an option to edit existing posts.
I have an EditPost xml file which embeds a file called attachment_item. This in turn embeds an xml file called EditAttachmentsLayout. I can post code from the first 2 files if needed, but I don't think the problem is in there.
The EditAttachmentsLayout page uses 2 RecyclerViews; one for images, and another for other files. Code is here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The problem is that when the Attachments recyler has items to display, it places some sort of overlay over the first (and only the first) image, like so:
If I hit the Cross button over the thumbnail (or the cross button on the attachment itself), the attachment is removed and the image then appears, as such:
It's as if the recycler is placing an overlay of some sort over the first image in the list. I have tried all sorts of things to address it, such as adding spacing to try to force the two recyclers apart, and switching to a GridView, as below:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:rowCount="4">
<android.support.v7.widget.RecyclerView android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="0"
android:scrollbars="none"/>
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_marginBottom="10dp"/>
<android.support.v7.widget.RecyclerView android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="2"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:scrollbars="none"/>
</GridLayout>
Unfortunately, the issue persists. The image is always covered, until I remove the attachment.
Any ideas...? I am stumped with this one.
EDIT:
Here is the code which sets up the recycler views:
private void SetupRecycler()
{
RecyclerView imagesRecyclerView = FindViewById<RecyclerView>(Resource.Id.edit_images_recycler);
RecyclerView attachmentsRecyclerView = FindViewById<RecyclerView>(Resource.Id.edit_attachments_recycler);
LinearLayoutManager imagesLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.Horizontal, false);
LinearLayoutManager attachmentsLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.Vertical, false);
imagesRecyclerView.SetLayoutManager(imagesLayoutManager);
attachmentsRecyclerView.SetLayoutManager(attachmentsLayoutManager);
IList<DeviceFile> localFiles = _fileUtil.GetLocalFiles(_postEntry.MobileId);
_editImageAdapter = new EditImageAdapter(_postEntry, localFiles.Where(file => file.IsThumbnail).ToList());
_editAttachmentAdapter = new EditAttachmentAdapter(_postEntry, localFiles.Where(file => !file.IsThumbnail).ToList());
imagesRecyclerView.SetAdapter(_editImageAdapter);
attachmentsRecyclerView.SetAdapter(_editAttachmentAdapter);
_editImageAdapter.LocalFileDeleted += LocalFileDeleted;
_editImageAdapter.UploadedFileDeleted += UploadedFileDeleted;
_editAttachmentAdapter.LocalAttachmentDeleted += LocalFileDeleted;
_editAttachmentAdapter.UploadedAttachmentDeleted += UploadedFileDeleted;
}
EDIT 2:
So here is the overlay which adds a removal button to the image when the post is in edit mode. Apologies for not including it earlier, I didn't build this app so don't know everything about it:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginRight="20dp"
android:layout_width="#dimen/edit_image_size"
android:layout_height="#dimen/edit_image_size">
<ImageView
android:background="#drawable/image_background"
android:id="#+id/attachment_image"
android:scaleType="fitXY"
android:layout_width="#dimen/edit_image_size"
android:layout_height="#dimen/edit_image_size"/>
<ImageButton
android:background="#drawable/rounded_button_secondary"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_alignTop="#id/attachment_image"
android:layout_alignRight="#id/attachment_image"
android:id="#+id/delete_attachment_button"
android:src="#drawable/icon_of_cross"
android:tint="#color/white"
android:padding="5dp"
android:layout_margin="5dp"
android:layout_width="25dp"
android:layout_height="25dp" />
Just for a bit of clarity, I have included some more screenshots, with multiple images and attachments. If there are both images and attachments in the post, the first image to be loaded (the one firthest right) will have the overlay:
Once I click the cross button to remove the first attachment, the attachment is gone (as expected) and the image is visible again:
Very strange!
Suggestions:
1. Try to set parent linear layout height to match_parent
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> // **this line here**
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Have you tried to see if you are having an issues with the main thread
RunOnUIThread(() => {}) - to update the adapters
Try notifying the recycler adapters for the changes by using:
_editImageAdapter.NotifiyDatasetChanged()
_editImageAdapter.NotifiyDatasetChanged()

Bring to Button front while having two ConstraintLayout

I'm trying to implement the following design on Android.
I know that to have the button at that position I should have two constraint layout; one for whole change password form and one for change password form without the Save button and then set the Save button's Top and Bottom constraint to the second ConstraintLayout.
But when I do this, the button goes behind the form, and therein lies the problem:
Here is my XML:
<android.support.design.widget.CoordinatorLayout 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=".ChangePasswordActivity">
<include
android:id="#+id/changePasswordBar"
layout="#layout/top_bar_full"></include>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.constraint.ConstraintLayout
android:id="#+id/changePasswordCTL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/activities_constraint_top_bottom"
android:layout_marginEnd="#dimen/activities_constraint_start_end"
android:layout_marginStart="#dimen/activities_constraint_start_end"
android:layout_marginTop="#dimen/activities_constraint_top_bottom"
android:background="#drawable/radius_background_exchange"
android:elevation="5dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
// some EditText and TextView views here
</android.support.constraint.ConstraintLayout>
<br.com.simplepass.loading_button_lib.customViews.CircularProgressButton
android:id="#+id/changePasswordBT"
style="#style/customButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:fontFamily="#font/sans_web_medium"
android:text="#string/finish"
android:textAllCaps="false"
android:textColor="#android:color/white"
android:textSize="#dimen/signinup_button_font_size"
app:initialCornerAngle="5dp"
app:layout_constraintBottom_toBottomOf="#+id/changePasswordCTL"
app:layout_constraintEnd_toEndOf="#+id/changePasswordCTL"
app:layout_constraintStart_toStartOf="#+id/changePasswordCTL"
app:layout_constraintTop_toBottomOf="#+id/changePasswordCTL"
app:spinning_bar_color="#android:color/white"
app:spinning_bar_padding="6dp"
app:spinning_bar_width="4dp" />
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
When elevation isn't in the picture, views that are defined later in the XML file will draw "on top" of views defined earlier. However, your password form has android:elevation="5dp", and this will override the normal drawing order.
To fix, add elevation to the button as well. android:elevation="5dp" should be enough, since then they're at the same elevation and the normal rules should apply. But you could give it more elevation to guarantee that it always draws on top of the password form.
There is a 5dp elevation on the form and no elevation on the button, so it is partially obscured. Increase the button elevation to at least 5dp.
android:elevation="5dp"
You could achieve such design by using a CoordinatorLayout.
Example:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="180dp"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:background="#color/primary" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_camera"
app:layout_anchor="#id/header"
app:layout_anchorGravity="bottom|center_horizontal" />
</android.support.design.widget.CoordinatorLayout>
just use the following to anchor the layout of your button to the layout of your library view:
app:layout_anchor= "id_of_password_form_layout"

Android: positioning of Floating Action Button unpredictable

Some of my floating action buttons don't remain where I want, and I cannot understand why.
The first is how they should be (and actually sometimes it works), the other two images show how they behave sometimes... and I cannot find a "pattern" in this behavior.
This is the layout (only one half):
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/lay_attivita_edit_ubicazioni"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="#dimen/list_padding_lateral"
android:paddingRight="#dimen/list_padding_lateral">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:id="#+id/container_attivita_edit_origini">
<TextView
style="#style/FieldLabel"
android:layout_marginTop="20dp"
android:text="#string/attivita_edit_origini" />
<ListView
style="#style/ListView"
android:id="#+id/list_attivita_edit_origini"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:fadeScrollbars="false"
android:background="#drawable/border_rectangle" />
</LinearLayout>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
style="#style/FloatingActionButton.Small"
android:id="#+id/fab_attivita_edit_ubicazioni_edit_origini"
app:layout_anchor="#id/list_attivita_edit_origini"
app:layout_anchorGravity="top|right|end" />
</android.support.design.widget.CoordinatorLayout>
I tried also to se anchor and anchorGravity programmatically but the result is the same. It could happen because depending on some logic one of the two sections could not be visible, in case I make them invisible at the end of OnCreateView.
It doesn't depend on the visibility of the "anchor list" because the fab move even if I always leave both the lists visible.
I tried also to change programmatically anchor and anchorId of the fab at every change of visibility of them or of their lists, nothing.
CoordinatorLayout.LayoutParams editOrigineFabParams = (CoordinatorLayout.LayoutParams)editOrigineFab.LayoutParameters;
editOrigineFabParams.AnchorId = Resource.Id.list_attivita_edit_origini;
editOrigineFabParams.AnchorGravity = (int)(GravityFlags.Top | GravityFlags.Right | GravityFlags.End);
editOrigineFab.LayoutParameters = editOrigineFabParams;
With the same conditions/code sometimes they work and sometimes they don't. It looks like a bug in Android. I tried with Android 7.0 and 7.1, Xamarin.Android.Support.Compat.25.3.1.
Anyone who had a similar problem or who has an idea of what could be the reason?
Use FAB by james montemagno.
Add FAB by james montemagno from nuget to your project.
https://www.nuget.org/packages/Refractored.FloatingActionButton/
<Refractored.Fab.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_margin="16dp"
android:src="#drawable/ic_action_content_new"
app:app_colorNormal="#color/primary"
app:app_colorPressed="#color/primary_pressed"
app:app_colorRipple="#color/ripple" />
use layout_gravity for positioning .
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:src="#drawable/ic_edit"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp" / >

Circular reveal over top of other views gives error "cannot start this animator on a detached view"

i had gone through research about for couple of days but didn't get it resolved. Problem in this Question is similar to mine but I couldn't solve my issue using this either.
I had tried to get the circular reveal effect just like whatsapp where the revealed view will be inflated over the top of other views. In my case when I apply the animation on a layout already present in the layout.xml of current java class then its work fine but the problem is that the revealing layout which in my case is LInearLayout will push the other contents(which are under it) down and make place for it.
My layout in this case is as follow,
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<io.codetail.widget.RevealFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/reveal_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/icon_camera" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Gallery" />
</LinearLayout>
<!-- Other 2 icons here-->
</LinearLayout>
</io.codetail.widget.RevealFrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter Name" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK" />
LinearLayout/>
my reveal layout will push the EditText and button down to make place for it but i want to reveal over the top of them..
Then I tried to put the revealing view code in another reveal-layout.xml file and inflate that layout to a View(LinearLayout in my case) created in javacode. And then try to apply the revealing effect on this LinearLayout but it gives me this "cannot start this animator on a detached view" exception.
My revealing-layout.xml looks like
<io.codetail.widget.RevealFrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/reveal_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<ImageButton
android:layout_width="70dp"
android:layout_height="70dp"
android:background="#drawable/icon_camera" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Gallery" />
</LinearLayout>
<!-- Other 2 icons here-->
</LinearLayout>
</io.codetail.widget.RevealFrameLayout>
In button click i call function revealView();
which looks as below,
public void revealView()
{
int cx = (mRevealView.getLeft() + mRevealView.getRight());
int cy = mRevealView.getTop();
int radius = Math.max(mRevealView.getWidth(), mRevealView.getHeight());
// and all animations here, the animator is working fine so i did not put the code here
}
If i initialize mRevealView in my MainActivity onCreate() methoed as, mRevealView=(LinearLayout)findviewbyid(R.id.reveal_items) and inflate and assign view to it then the animator will work fine on this view. But when i try to create new layout like,
mRevealView=new LinearLayout(this) and set its parameters etc everything then it will gives this error when i apply animator on it.
Cannot start this animation on a detached view.
What I am doing wrong here can anybody suggest me.
Try to put your reveal code in a ViewTreeObserver of intended reveal-layout, something like this:
boolean reveal = false;
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
reveal = true;
}
});
LinearLayout layout = (LinearLayout) findViewById(R.id.reveal_items);
layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(reveal) {
reveal = false;
// start reveal animation here
// ...
}
// for SDK >= 16
ll.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
To achieve a similar effect like whatsapp using the Circular Effect like whatsapp library you mentioned i first set my parent view as FrameLayout. This parent Framelayout includes two childrens first is LinearLayout and second is FrameLayout(Here comes the code you want to display on top of view written in LinearLayout). Write all your code which you want display on the screen in the first LinearLayout and the reveal effect code in second FrameLayout as i mentioned. Its simply the use of FrameLayout property. You are good to go.
You can use the same java code provided in the discription of the library.

Make programmatically added fragment clickable, uniquely identifiable

I'm running into some problems trying to figure out how to make fragments that I have programmatically added into a LinearLayout clickable. I'm using fragments because they will be in multiple activities and it was a good way for me to create a layout like this:
http://i.stack.imgur.com/P4lOG.png
But, if there's a better way to do this that would make the process of making it clickable, I'm certainly open to changing things up.
Anyway, I'm adding the fragments to the LinearLayout, jobsList, like so:
FragmentManager fragmentManager = getFragmentManager();
int count = 2;
for (int i = 0; i < count; i++) {
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
Bundle bundle = new Bundle();
bundle.putInt("jobID", i + 1);
jobFragment job = new jobFragment();
job.setArguments(bundle);
fragmentTransaction.add(R.id.jobsList, job, Integer.toString(i));
fragmentTransaction.commit();
}
The count of 2 is just a placeholder for now, later there will be an arbitrary number of jobs.
Here is the layout, it's a bit of a mess but I got all the specific weights the way I wanted this way.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rootContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".2" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/basicPort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background"
android:text="Port" />
<TextView
android:id="#+id/basicLoadOrEmpty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background"
android:text="Load/Empty" />
<TextView
android:id="#+id/basicInOrOut"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/background"
android:text="In/Out" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".6"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".333" >
<TextView
android:id="#+id/basicContainerNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".4"
android:background="#drawable/background"
android:text="Container #" />
<TextView
android:id="#+id/basicChassisNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".4"
android:background="#drawable/background"
android:text="Chassis #" />
<TextView
android:id="#+id/basicContainerType"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight=".2"
android:background="#drawable/background"
android:text="Cont. Type" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".333" >
<TextView
android:id="#+id/basicDirectionArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".2"
android:background="#drawable/background"
android:text="Direction" />
<TextView
android:id="#+id/basicCustomer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight=".8"
android:background="#drawable/background"
android:text="Customer Location" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".333" >
<TextView
android:id="#+id/basicSteamshipLine"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".4"
android:background="#drawable/background"
android:text="Steamship Line" />
<TextView
android:id="#+id/basicBKG_BOL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".6"
android:background="#drawable/background"
android:text="BKG-BOL#" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight=".2" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/basicStatus1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:background="#drawable/background"
android:text="Status 1" />
<TextView
android:id="#+id/basicStatus2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:background="#drawable/background"
android:text="Status 2" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="20dp" />
</LinearLayout>
My question to you is, is it possible to make these fragments clickable and uniquely identifiable, and if so, what is the best way to go about doing that?
Thank you for your help!
What you could do is:
Modify the layout of your fragment, so it uses the RelativeLayout (now its probably LinearLayout right?). By modify I mean either use RelativeLayout INSTEAD of LinearLayout (more complicated but i think a bit better), or put your LinearLayout INSIDE RelativeLayout.
Place a view that matches in size the size of the fragment, on top of your textViews. Add an onClickListener to it that performes the code on clicks.
First - fragments are not clickable, layouts and their children are. A Fragment can handle the click action for things that occur in its layout but you do not "click" the fragment.
Second - sounds like you're confused about how to use fragments and what a Fragment actually does. A Fragment is like an Activity with some parts missing. A Fragment has its own lifecycle and can be used to perform many of the same tasks as an Activity the difference being that (1) a Fragment is "hosted" by an activity that provides the missing functions and does not run on its own (2) a Fragment can run in the background with no UI (I do not know of a background activity yet).
You do not need to/should not be using Fragments for what you are trying to do.
Your layout is really just a series of TextViews. You should be able to make that layout in XML reuse that layout file - by simply getting a LayoutInflater anywhere else in your app that you want to. If things got really crazy you could create a custom TextView class to provide detailed functionality but you should not be using 10 fragments, each with one TextView to make that layout work.
I just wanted to follow up on things in case anybody stumbles upon this answer in the future. It turns out using fragments was a bad idea. While I was able to make them clickable and identifiable through a bit of a hack job, I ran into problems later on when I was trying to fix layout issues. So, thanks to #Rarw I looked into using a LayoutInflater instead.
And that was much easier! I just made the layout xml file, used the LayoutInflater to add it to a LinearLayout and added that to the list. Makes things much easier down the road:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout container = new LinearLayout(this);
inflater.inflate(R.layout.basic, container, true);
container.setId(i);
list.addView(container, params);
container.setClickable(true);
container.setOnClickListener(this);
A hacky solution is to place a transparent button on top of the entire fragment, have the fragment extend onClickListener, and set the button's onClickListener to this.
One way to create such a button:
Use a constraintLayout as the root layout for the xml.
As the last of child of the constraintLayout, create a button, constrain it to occupy entire fragment by setting layout_constrainXXX to corner elements.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<!-- The remaining properties of the layout -->
<!-- All the children of the layout -->
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:background="#00000000"
android:id="#+id/fragment_button" />
</android.support.constraint.ConstraintLayout>
Note that you can do this other ways too, such as in a RelativeLayout
Then in the java/kotlin file, extend onClickListener.
override fun onClick(p0: View?) {
// Whatever you want to do here
}
In method onActivityCreated, set the transparent button's listener as:
var button : Button = fragment_button
button.setOnClickListener(this)

Categories

Resources