How do I create a square grid using a ConstraintLayout with labels for the rows that are vertically centered? - android-constraintlayout

I need to create a square grid with labels for the rows on the left side. The grid should use the entire space available on the device while keeping width=height. Because this grid has several rows and several columns automatically adjusted, I thought that using a customized ConstraintLayout would fit that requirement.
In the code below, which is used in a "portrait" layout, if I set the layout_width of the SCFrame view to
match_parent: the size of the grid is as expected, but the gravity of the textView10 and textView11 fields is not applied
wrap_content: the grid collapses to 0dpx0dp
0dp: same as wrap_content, which in my opinion is not in line with the documentation of the ConstraintLayout that says "Using 0dp, which is the equivalent of MATCH_CONSTRAINT"
xxxdp: the SCFrame grid is square with width=xxxdp and height=xxxdp, and the gravity of the textView10 and textView11 fields is correctly applied
What should I change in the following code to get a grid that is square and uses the entire width of the screen (whatever the used device and allowing space for the labels column) and with the correct gravity for the labels?
<?xml version="1.0" encoding="utf-8"?>
<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/scMainFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintVertical_chainStyle="spread_inside"
app:layout_optimizationLevel="chains"
tools:context=".MainActivity"
tools:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:id="#+id/textView10"
android:layout_width="14dp"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="A"
android:background="#FF0000"
app:layout_constraintTop_toTopOf="#+id/SCFrame"
app:layout_constraintRight_toLeftOf="#+id/SCFrame"
app:layout_constraintBottom_toTopOf="#+id/textView11" />
<TextView
android:id="#+id/textView11"
android:layout_width="14dp"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="B"
android:background="#FF0000"
app:layout_constraintTop_toBottomOf="#+id/textView10"
app:layout_constraintRight_toLeftOf="#+id/SCFrame"
app:layout_constraintBottom_toBottomOf="#+id/SCFrame" />
<be.ema.sclibrary.SCConstraintLayout
android:id="#+id/SCFrame"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:background="#0000FF"
app:layout_constraintLeft_toRightOf="#+id/textView10"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<TextView
android:id="#+id/A1"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="this is A1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="#+id/A2"
app:layout_constraintBottom_toTopOf="#+id/B1" />
<TextView
android:id="#+id/A2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="this is A2"
app:layout_constraintLeft_toRightOf="#+id/A1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#+id/B2" />
<TextView
android:id="#+id/B1"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="this is B1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="#+id/A1"
app:layout_constraintRight_toLeftOf="#+id/B2"
app:layout_constraintBottom_toBottomOf="parent" />
<TextView
android:id="#+id/B2"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="this is B2"
app:layout_constraintLeft_toRightOf="#+id/B1"
app:layout_constraintTop_toBottomOf="#+id/A1"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</be.ema.sclibrary.SCConstraintLayout>
</android.support.constraint.ConstraintLayout>
This is the code for the customized ConstraintLayout:
class SCConstraintLayout extends android.support.constraint.ConstraintLayout {
public SCConstraintLayout(Context context) {
super(context);
}
public SCConstraintLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SCConstraintLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int chosenDimension = 0;
int mode = 0;
if (ScMain.isLandscapeOriented) {
chosenDimension = MeasureSpec.getSize(heightMeasureSpec);
mode = MeasureSpec.getMode(heightMeasureSpec);
} else {
chosenDimension = MeasureSpec.getSize(widthMeasureSpec);
mode = MeasureSpec.getMode(widthMeasureSpec);
}
int width = MeasureSpec.makeMeasureSpec(chosenDimension, mode);
int height = MeasureSpec.makeMeasureSpec(chosenDimension, mode);
// setMeasuredDimension(width, height);
super.onMeasure(width, height);
}
}

Related

Customised InfoWindow of Google Map does not render elevation shadow in Android

I'm using InfoWindow to render any information for marker.
In Android, we can define shadow with elevation.
But the shadow defined by elevation is not rendered for InfoWindow.
The layout of infoWindow is like this
<RelativeLayout
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="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/background"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:elevation="4dp"
>
<TextView
android:id="#+id/main_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:textSize="14sp"
android:textStyle="bold"
tools:text="main text"
/>
<TextView
android:id="#+id/sub_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/main_text"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:textSize="11sp"
tools:text="sub text"/>
</RelativeLayout>
Shape is like this
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="500dp"/>
<solid android:color="#color/white"/>
</shape>
Code snippet is like this
googleMap?.setInfoWindowAdapter(object: GoogleMap.InfoWindowAdapter {
override fun getInfoContents(marker: Marker?): View? {
return null
}
override fun getInfoWindow(marker: Marker?): View? {
return layoutInflater.inflate(R.layout.map_info_window, null)
}
})

How can I create a "square" ConstraintLayout that is included in a chain of widgets?

I try to create a "square" ConstraintLayout by extending the ConstraintLayout class as follows:
class SCConstraintLayout extends android.support.constraint.ConstraintLayout {
public SCConstraintLayout(Context context) {
super(context);
}
public SCConstraintLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SCConstraintLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int chosenDimension = 0;
int mode = 0;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
chosenDimension = MeasureSpec.getSize(heightMeasureSpec);
mode = MeasureSpec.getMode(heightMeasureSpec);
} else {
chosenDimension = MeasureSpec.getSize(widthMeasureSpec);
mode = MeasureSpec.getMode(widthMeasureSpec);
}
int side = MeasureSpec.makeMeasureSpec(chosenDimension, mode);
super.onMeasure(side, side);
setMeasuredDimension(side, side);
}
}
If I include a widget with this custom class into a chain of widgets such as in the following landscape-oriented layout
<?xml version="1.0" encoding="utf-8"?>
<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/scMainFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
app:layout_optimizationLevel="chains"
tools:context=".MainActivity"
tools:layout_behavior="#string/appbar_scrolling_view_behavior">
<!-- gridFrame -->
<android.support.constraint.ConstraintLayout
android:id="#+id/gridFrame"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintVertical_chainStyle="spread_inside"
app:layout_optimizationLevel="chains"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="#+id/Report"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
>
<!-- column headers -->
<android.support.constraint.ConstraintLayout
android:id="#+id/colHeaders"
android:layout_width="0dp"
android:layout_height="14dp"
android:orientation="horizontal"
app:layout_constraintVertical_chainStyle="spread_inside"
app:layout_optimizationLevel="chains"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#+id/SCFrame"
app:layout_constraintLeft_toLeftOf="#+id/SCFrame"
app:layout_constraintRight_toRightOf="#+id/SCFrame"
>
<TextView
android:id="#+id/textView0"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="A"
android:background="#FF0000"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
<!-- row headers -->
<android.support.constraint.ConstraintLayout
android:id="#+id/rowHeaders"
android:layout_width="14dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_optimizationLevel="chains"
app:layout_constraintTop_toTopOf="#+id/SCFrame"
app:layout_constraintBottom_toBottomOf="#+id/SCFrame"
app:layout_constraintRight_toLeftOf="#+id/SCFrame"
app:layout_constraintLeft_toLeftOf="parent"
>
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="1"
android:background="#FF0000"
app:layout_constraintVertical_chainStyle="spread_inside"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
<be.ema.sclibrary.SCConstraintLayout
android:id="#+id/SCFrame"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#00FF00"
app:layout_constraintLeft_toRightOf="#+id/rowHeaders"
app:layout_constraintTop_toBottomOf="#id/colHeaders"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
>
<TextView
android:id="#+id/A1"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="this is A1"
android:background="#0000FF"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</be.ema.sclibrary.SCConstraintLayout>
</android.support.constraint.ConstraintLayout>
<TextView
android:id="#+id/Report"
android:layout_width="200dp"
android:layout_height="0dp"
android:text="This is the report"
android:background="#FFFF00"
app:layout_constraintLeft_toRightOf="#+id/gridFrame"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</android.support.constraint.ConstraintLayout>
and if I display it on a "Nexus 6" in the emulator of Android Studio for instance it looks like the SCFrame is only partially square:
the A1 TextView is square (i.e. its width is equal to its height)
however the width of the SCFrame itself is different from its height
How should I change the SCConstraintLayout class or the xml lay-out to get the SCFrame view perfectly square (i.e. its width is equal to its height) when displayed on a device?
NB: in my real application, SCFrame has several rows and columns. And there are several other widgets like buttons and textviews instead of the Report textview.
You just need the top level to be a ConstraintLayout. The nested ones and the custom class aren't needed. As for the square-shaped TextView, you can use the aspect ratio attribute.

A part of an activity displaying listview in android

I want to display the list view in half of the screen and the other half contains some static content. When i tried to put the listview, the whole screen is repeated in the loop. I want only that particular part the screen in listview. Can anyone help?
This is my MainActivity.java
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i=0;i<6;i++){
HashMap<String, String> hm = new HashMap<String,String>();
hm.put("text", menu[i]);
hm.put("icon", Integer.toString(image[i]) );
aList.add(hm);
}
String[] from = { "icon","text" };
int[] to = { R.id.icon,R.id.text};
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.activity_test_main, from, to);
ListView listView = ( ListView ) findViewById(R.id.list);
listView.setAdapter(adapter);
This my activity_test_main.xml
<?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"
android:background="#drawable/new_background"
>
<ImageView
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_marginTop="30dip"
android:layout_gravity="center_horizontal"
android:src="#drawable/katrina" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Katrina"
android:textColor="#FFFFFF"
android:textStyle="italic"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="katrina#gmail.com"
android:textColor="#FFFFFF"
android:textStyle="italic"
android:layout_gravity="center_horizontal"
android:layout_marginTop="5dip"/>
<RelativeLayout
android:id="#+id/single_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dip">
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dip"
android:textColor="#FFFFFF"/>
<ImageView
android:id="#+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
If I'm getting this right you want to display the ListView below the arrow ImageView?
You can simply put the ListView below the ImageView inside the RelativeLayout, then set the android:layout_below param to the id of the ImageView...arrow and finally make sure your ListView's id is set to list

TransitionManager scene animation behavior with root layout

I'm testing out the Android Kit Kat transition feature. When the transition happens, the margins of the root layout are getting padded. I find this behavior strange.
The source
public class MainActivity extends ActionBarActivity {
Button btn;
TextView txt;
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView)findViewById(R.id.text);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ViewGroup root = (ViewGroup)findViewById(R.id.root);
Scene scene = Scene.getSceneForLayout(root, R.layout.activity_main2, MainActivity.this);
TransitionManager.go(scene);
}
});
}
...
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:id="#+id/root"
tools:context="com.sebouh00.test.scenes.MainActivity">
<Button android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:layout_marginBottom="12dp"/>
<TextView
android:id="#+id/text"
android:layout_below="#id/btn"
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="18dp"/>
</RelativeLayout>
activity_main2.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:id="#+id/root"
tools:context="com.sebouh00.test.scenes.MainActivity">
<Button android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:layout_marginBottom="12dp"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/btn"
android:id="#+id/img"
android:src="#drawable/flag"
android:layout_marginBottom="12dp"/>
<TextView
android:id="#+id/text"
android:layout_below="#id/img"
android:text="#string/hello_world"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="18dp"/>
</RelativeLayout>
Results in this unless I remove the paddings from activity_main2.xml
Any ideas why?
It's because the View produced by inflating activity_main2 gets inserted into the Scene's root, i.e. your R.id.root RelativeLayout, so the padding from R.id.root is still applied.

Delayed ContextMenu on ListView

I have an Activity with a ListView. You long-press each row to get a ContextMenu. At the bottom of the ListView is an EditText box. It looks like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="3dp"
android:layout_marginTop="3dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/TVReviewItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"
android:layout_weight="90"
android:text="Item Name"
android:textSize="20sp" />
<Spinner
android:id="#+id/spinnerSort"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:gravity="left" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#bbb" >
</LinearLayout>
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:longClickable="true"
android:scrollbars="none" >
</ListView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#bbb" >
</LinearLayout>
<EditText
android:id="#+id/etTweetReview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:ems="10"
android:hint="Write a Review"
android:imeOptions="actionDone"
android:inputType="textCapSentences|textMultiLine"
android:maxLength="140"
android:maxLines="4"
android:minLines="1"
android:paddingBottom="9dp"
android:paddingTop="9dp"
android:singleLine="false" >
<requestFocus />
</EditText>
The problem: The ContextMenu will not show up until you physically press the cursor inside the EditText box (even though I am already requesting focus) and then LongPress the List row. If you long-press the list row FIRST, nothing happens. Here is the OnCreateContextMenu:
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
android.view.MenuInflater inflater = getActivity()
.getMenuInflater();
inflater.inflate(R.menu.reviews_context, menu);
menu.setHeaderTitle("Available Actions");
android.view.MenuItem Edit = menu.findItem(R.id.edit);
android.view.MenuItem Delete = menu.findItem(R.id.delete);
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
int position = info.position;
ListView lv = (ListView) v;
int firstVisible = lv.getFirstVisiblePosition();
View rowView = lv.getChildAt(position - firstVisible);
ReviewUser = ((TextView) rowView.findViewById(R.id.labelUser))
.getText().toString();
ReviewWords = ((TextView) rowView.findViewById(R.id.labelComment))
.getText().toString();
if (Rateit.isUserLoggedIn == true) {
if (Rateit.username.equals(ReviewUser) {
Edit.setVisible(true);
Delete.setVisible(true);
} else {
Edit.setVisible(false);
Delete.setVisible(false);
}
} else {
Edit.setVisible(false);
Delete.setVisible(false);
}
}
I've tried this with the Super above and below the other content. Can anyone see what's wrong?
UPDATE: New info. I found if the ListView scrolls, you have to scroll to the bottom THEN it will allow you to access ContextMenu if you try. In this case, it has nothing to do with EditText box.
I figured it out. In my row layout file (not shown), I have three buttons. I had to set each to:
android:focusable="false"
Simple fix apparently.