GridView items clipped and different heights - java

After creating a GridView, I noticed that some GridView items have a bigger height than others. What needs to be done to ensure that all GridView items are the same height(regardless of screen orientation & different text lengths) + to ensure that GridView content doesn't get clipped?
sw600dp/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
tools:context=".MainActivity">
<GridView
android:id="#+id/abslistview_main"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:horizontalSpacing="20dp"
android:verticalSpacing="20dp"
android:numColumns="auto_fit"
/>
</RelativeLayout>
sw600dp/item_abslistview.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
android:id="#+id/cardview_mainitem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="4dp"
card_view:cardCornerRadius="3dp">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:background="#drawable/ripple_background"
android:orientation="horizontal">
<ImageView
android:id="#+id/griditem_img"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp" />
<TextView
android:id="#+id/griditem_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="#android:color/white"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
</android.support.v7.widget.CardView>
MainActivity.java
public class MainActivity extends Activity {
private ArrayList<MainItem> mainArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AbsListView absListView = findViewById(R.id.abslistview_main);
settingData();
ArrayAdapter<MainItem> adapter = new AbsListViewAdapter(this, R.layout.item_abslistview, mainArrayList);
absListView.setAdapter(adapter);
}
private void settingData() {
mainArrayList = new ArrayList<>();
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "Fruit and vegetables"));
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "Potatoes, bread, rice, pasta and other starchy carbohydrates"));
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "Oils and spreads"));
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "Dairy and alternatives"));
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "Beans, pulses, fish, eggs, mint and other proteins"));
mainArrayList.add(new MainItem(R.drawable.ic_info_outline_white, "More information"));
}
}

Use fixed height instead of wrap_content in the xml of your custom list item.
If you want to show all items of the grid view instead of scrolling behavior, use nested linear layouts with weights, or try some other layouts.

try this: Change the attribute of the Image view in the file to a specific height of your choice. Thanks
android:layout_height="50dp"
That might help in solving the problem. The specified attribute would make it to have a definite height and remains equal for all items .

Related

How to correctly resize a View so its bottom is aligned with other View's top in ConstraintLayout programatically?

I have a ScrollView and a FrameLayout inside a ConstraintLayout. When I click a button, I want the ScrollView layout to resize so the bottom of the ScrollView is aligned with the top of the FrameLayout. However, the constraints won't change when the button is clicked.
I've tried to put the ScrollView inside a LinearLayout instead, but that didn't work either.
When button is clicked:
private void fixTableConstraint() {
ConstraintLayout constraintLayout = findViewById(R.id.home_constraint_layout);
View scrollView = findViewById(R.id.homeScreenScroll);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(R.id.homeScreenScroll, ConstraintSet.BOTTOM, R.id.timeMenuOverlay, ConstraintSet.TOP, 0);
constraintSet.applyTo(constraintLayout);
ConstraintLayout.LayoutParams cl = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT);
scrollView.setLayoutParams(cl);
}
XML 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/home_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:id="#+id/homeScreenScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.2"
tools:layout_editor_absoluteX="0dp">
<TableLayout
android:id="#+id/homescreenTable"
android:layout_width="match_parent"
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" />
</ScrollView>
<FrameLayout
android:id="#+id/timeMenuOverlay"
android:layout_width="match_parent"
android:layout_height="152dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<fragment
android:id="#+id/timeMenuFragment"
android:name="multicus.com.scheduleplannerv2.TimeMenuFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
Normal Layout:
https://imgur.com/VsfSgVa
What happens in my case when button is clicked:
https://imgur.com/pXT8v6W
What I actually want:
https://imgur.com/6OML007
Your constraints changes will not work because you have
ScrollView layout_height = "match_parent"
You can do it like this
<ScrollView
android:id="#+id/homeScreenScroll"
android:background="#color/green_dark"
android:layout_width="match_parent"
android:layout_height="0dp" // this is important
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/timeMenuOverlay" // and this
tools:layout_editor_absoluteX="0dp">
<TableLayout
...
/>
</ScrollView>
<FrameLayout
android:id="#+id/timeMenuOverlay"
android:visibility="gone" // !!
android:layout_width="match_parent"
android:layout_height="152dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
Instead of changing your layout constraints, change only the visibility.
timeMenuOverlay visibility => GONE, expand your ScrollView to the bottom
timeMenuOverlay visibility => VISIBLE => expected result

How to make the layouts in a viewflipper random

I'm trying to display layouts randomly in a view flipper (I have 4 layouts - they will be many more). This is what I have so far
public class MainActivity extends AppCompatActivity {
Random mRandom = new Random();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewFlipper simpleViewFlipper = (ViewFlipper) findViewById(R.id.simpleViewFlipper);
Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
Animation out = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
simpleViewFlipper.setInAnimation(in);
simpleViewFlipper.setOutAnimation(out);
simpleViewFlipper.setFlipInterval(3000);
simpleViewFlipper.setAutoStart(true);
simpleViewFlipper.setDisplayedChild(mRandom.nextInt(4));
}
}
I want them to randomly show and never stop.
Please bare in mind that I'm a beginner :)
Thanks.
Where are you getting your images from? Are the images in your DB or only in SRC folder? Any attemps on the coding? Give us a little more information.
For example...
setContentView(R.layout.yourxml);
ArrayList<uploadsclass> currentuploads = new ArrayList<uploadsclass>();
currentuploads.add(new uploadsclass("MYBRAND NEW AUDI", "1.6TDI, 220 CCM, diesel", R.drawable.audi));
uploadsclassadapter addtoList = new uploadsclassadapter(this, currentuploads);
// Get a reference to the ListView, and attach the adapter to the listView.
ListView listView = (ListView) findViewById(R.id.listview_ids);
listView.setAdapter(addtoList);
yourxml.xml:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview_ids"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" />
your listitems.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:minHeight="?android:attr/listPreferredItemHeight">
<ImageView
android:id="#+id/oneCarImage"
android:layout_width="50dp"
android:layout_height="64dp"
android:layout_weight="0.04" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
android:paddingLeft="16dp">
<TextView
android:id="#+id/quickInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/quickCharacteristics"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

How to fill page with overlay

I have a TRANSPARENT overlay in my android app that when user click on it,it fade but it can't fill all activity like below image
MainActivity :
<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"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
</RelativeLayout>
OverlayActivity :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
Java :
public class MainActivity extends Activity {
private ImageView mOverLayImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Dialog overlayInfo = new Dialog(MainActivity.this);
overlayInfo.requestWindowFeature(Window.FEATURE_NO_TITLE);
overlayInfo.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
overlayInfo.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
overlayInfo.setContentView(R.layout.overlay_view);
overlayInfo.show();
mOverLayImage = (ImageView) overlayInfo.findViewById(R.id.over_lay_image);
mOverLayImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
overlayInfo.cancel();
}
});
}
}
Use FrameLayout. Each item added to FrameLayout is on top of the previous one, like in this example the second TextView is on top of the frist one, but since it is not fully opaque, you can see them both!
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:text="Blablabla"
android:background="#FFFFFFFF"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:textColor="#FFFFFF"
android:text="I am on top"
android:gravity="center"
/>
</FrameLayout>
Now all you need to do is show/hide the overlayed items and you are good to go.
Delete your overlay activity, and inside your main activity apply this code :
<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"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="This is Original View" />
<!-- This is your overlay -->
<RelativeLayout android:id="#+id/over_lay_page"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/over_lay_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#50220000"
android:onClick="clickedOverlay" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="This is Overlay View" />
</RelativeLayout>
</RelativeLayout>
Note that I added a line on your ImageView which runs a function when clicked, now on your java file add this function:
//The onClick on xml requires a function of signature void(View) which is the clicked view (in this case the ImageView)
public void clickedOverlay(View view)
{
//ImageView is clicked
RelativeLayout rlLayout = (RelativeLayout) findViewById(R.id.over_lay_page);
rlLayout.setVisibility(View.GONE);
}
This will make the RelativeLayout that contains the overlay views (including the ImageView which is clicked) to not only be invisible but not to interfere with anything. It also ignores input to it.
In case I misunderstood anything about your question feel free to correct me (I'm not sure I understood that completely).
Also if you want it to fade in or out or something like that you can do it with an AlphaAnimation.

Input type=number is not working

First of all , this is the problem on nexus 5 with default input method.
The problem is , if I use v4 fragment tab host with the edit-text (input type = number), when I type the number , then it will switch to alphabetical keypad, and nothing is input in the edit-text.
I am sure this is the problem with v4 fragment tab host as I tried tabhost it works, I use only activity instead of any tab host, it works. When input type = "text" , and switch to num pad , it works. I can capture onKeyDown event , too .
The only fail case is input type= number and the edit text is inside the v4 fragment tabhost
the layout of the tab fragment
<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" >
<EditText
android:id="#+id/edit_ratio"
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginBottom="5dp"
android:digits="0123456789."
android:inputType="number"
android:maxLength="4"
android:padding="5dp"
android:textSize="16sp" />
</RelativeLayout>
the layout of tab
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/tabBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal"
android:visibility="gone" >
<TabWidget
android:id="#android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</LinearLayout>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<FrameLayout
android:id="#+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
java of the main activity
public class Main extends ActionBarActivity {
public static FragmentTabHost tabHost;
public static LinearLayout tabBar;
private String[] tags = { "home", "form", "calculator", "phone", "partner", "about_us", "settings" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
tabBar = (LinearLayout) findViewById(R.id.tabBar);
tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
tabHost.addTab(
tabHost.newTabSpec(tags[0]).setIndicator(""),
HomeFragment.class, null);
}
}
Also, I only found it happen when using input method named "Simplified cangjie keyboard" with nexus 5 . So I wonder how to fix it . Really Thanks a lot.

How can I implement a ListView within a LinearLayout?

I am trying to make a simple Checkbook app, whose MainActivity stores a list of transactions. I would like a TextView at the top and bottom of the screen that show the account balance and an option to add a new transaction, respectively. I would like a list of transactions in between that scroll. I was able to implement a ListView and add a header and footer view, but if the transaction list exceeds the size of the screen the headers and footers can scroll off screen.
Is there any way to position a ListView within the linear layout, or freeze the headers/footers to stay on the screen?
Here is my XML file so far:
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
And here is my onCreate, which has no syntax errors but I am unable to click the footerview to add a transaction:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_checkbook);
ListView list = (ListView) findViewById(R.id.transaction_list_view);
// Create a new Adapter
mAdapter = new TransactionAdapter(list.getContext());
// Inflate footerView and headerView
LayoutInflater inflater = getLayoutInflater();
TextView headerView = (TextView) inflater.inflate(R.layout.header_view, null);
TextView footerView = (TextView) inflater.inflate(R.layout.footer_view, null);
// Set listener for footerView
footerView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Intent transactionIntent = new Intent(CheckbookActivity.this, AddTransactionActivity.class);
startActivityForResult(transactionIntent, ADD_TRANSACTION_REQUEST);
}
});
list.setAdapter(mAdapter);
}
use the below code. This will satisfy your requirement. I tried this and working for me.
Relative layout with below,above attributes. Relativelayout is better than Linear layout with weight method.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/relative"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:text="ListView Heading" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:gravity="center_horizontal"
android:text="ListView Footer" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/textView1"
android:layout_above="#id/textView2"
></ListView>
The UI will like this
Try this way, hope this will help you to solve your problem.
Instead of using header/footer just put as below code in your XML:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:id="#+id/header_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add_transaction_string">
</TextView>
</LinearLayout>
Yes, you can do it with weightsum and layout_weight in linearlayout and also you can create this type of view using RelativeLayout.
1) In LinearLayout just add weightsum="1" to your linearlayout and add layout_weight="0.2" to each of your header and footer and add layout_weight="0.6" to your listview.
2) In relativeLayout add alignParentTop to your header and alignParentBottom to your footer and set listview to layout_below="#+id/header" and layout_above="2+id/footer"
I found a possible solution for your problem from a similiar post. Hope this helps you.
For what you are trying to accomplish to freeze the header/footer. It will be easier to use a relative layout to position the header/footer then have your listview in the middle
<RelativeLayout ...>
<TextView
android:id="#+id/header_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="#string/default_header_string">
</TextView>
<ListView
android:id="#+id/transaction_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/header_view"
android:layout_above="#+id/footer_view">
</ListView>
<TextView
android:id="#+id/footer_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:text="#string/add_transaction_string">
</TextView>
</RelativeLayout>
You can use a LinearLayout for this task. But I don't recommend it as it's a bit "hacky".
Get all the elements in a array: Example:- (weatherArray)
Loop through all the elements :-
Example:-
mainLayout = ((LinearLayout)refreshObj.get("mainLayout"));
mainLayout.removeAllViews();
for (int i = 0; i < weatherArray.length(); i++) {
View childView = getLayoutInflater().inflate(R.layout.weather_row4_item, mainLayout,false);
TextView todayTempStatus = (TextView) childView.findViewById(R.id.todayTempStatus);
todayTempStatus.setText("");
}
This is an example without using listview, which we will populate lienarlayout using child view.

Categories