i trying to get a layout just like the image below for a game in android studio
currently my xml is
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.dreacot.testmymemory.Game">
<ImageView
android:id="#+id/imageView"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="53dp"
tools:layout_editor_absoluteY="136dp" />
<ImageView
android:id="#+id/imageView4"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="156dp"
tools:layout_editor_absoluteY="136dp" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="266dp"
tools:layout_editor_absoluteY="136dp" />
<ImageView
android:id="#+id/imageView6"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="53dp"
tools:layout_editor_absoluteY="285dp" />
<ImageView
android:id="#+id/imageView5"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="156dp"
tools:layout_editor_absoluteY="285dp" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="72dp"
android:layout_height="115dp"
app:srcCompat="#drawable/backside"
tools:layout_editor_absoluteX="266dp"
tools:layout_editor_absoluteY="285dp" />
i want more cards to be added on the next level eg lvl 2
do i need to make several layouts for each level?
also i want each card to show its face when it is clicked
and finally i feel i am not doing the right thing as i feel xml files cannot be called into the gameplay is there a better way to do this layout(maybe programmatically)?
could anyone help?
The way you are doing it is not the proper way to do it, In this way maybe you can achieve this for 6 cards. What if you have let's say 100 cards or may be 1000, will you add 100 images in Layout and get reference of 100 images in Activity and set Click Listeners and animations to turn the side on 100 images?
Use "GridView" and Adapter for your views, it will do your work with ease.
Check this: https://developer.android.com/guide/topics/ui/layout/gridview.html
You have to do it programmatically.
1. Use RecyclerView with GridLayoutManager to show your card as grid style.
2. Create a layout with just a CardView with single ImageView for your single card item.
3. Create an custom RecyclerView.Adapter<> and use it with RecyclerView to populate your card data on CardView.
4. Add onItemClick listener to Adapter to flip to the specific Card item and do something as per your needs.
Here are some useful links about RecyclerView:
Android RecyclerView with GridLayoutManager Example
Android GridLayoutManager with RecyclerView in Material Design
Simple Android grid example using RecyclerView with GridLayoutManager
Here is a good library for CardView animation.
Hope this will help~
I want to insert an image to an ImageView, which gets used as a background. This background is in a RecyclerView. When it gets loaded the first time, it looks like this:
But when I scroll to another item and scroll back, it looks like this (it should always look like this):
Here i add the image:
public void onBindViewHolder(StoryViewHolder holder, int position) {
holder.cardView.setMinimumHeight(height/3);
holder.layout.setMinimumHeight((int) ((float) width / 4));
//set image
Picasso.with(activity).load(MainPostAdapter.URL + 140 + ".png").
transform(new BlurTransform(holder.background.getContext())).fit().centerCrop().into(holder.background);
holder.background.setAlpha(0.25f);
}
And this is the image itself:
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/story_view_background"/>
What could the problem be?
EDIT:
whole XML (It doesn't show all of the code. Here is also pastebin:http://pastebin.com/8rJvSx7V):
<?xml version="1.0" encoding="utf-8"?>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/story_view_background"/>
<RelativeLayout
android:id="#+id/story_view_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="50px">
<ImageView
android:id="#+id/story_view_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/story_view_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:layout_below="#+id/story_view_image"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:gravity="center_horizontal"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
</FrameLayout>
try to set android:layout_height="150dp" for your CardView (don't use px!). Its child FrameLayout is unnecesarry (CardView is extending FrameLayout and have set same attributes set), remove it.
It's not so well written, all your Views have match_parent set for height, besides Image and Text views... Your item is probably trying to fit RecyclerView height in this case ("whole screen") and is measured without image at first time (Picasso async downloading, setting image when view is already measured). But when you inflate your View again (scroll and recycle) new list item will be measured differently, because Picasso will insert your image "in runtime", no need to async fetching (cache)
So I've googled, and scoured SO for an answer to what I think is probably a ridiculous oversight, but here goes.
I have a ListView that I'm populating with an ArrayAdapter that I'm building out of a list of objects I'm using elsewhere in my application. I have checked via getCount that there are items in the adapter, both before and after I call .setAdapter(). Nothing is showing up in my application however.
My main layout res/layout/playlistview:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/playlist_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#80000000"
android:gravity="center"
android:orientation="horizontal" >
<ListView
android:id="#+id/playlistview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#206"
android:background="#602" >
</ListView>
</LinearLayout>
(I set the colors so I could see what's going on more easily)
the textview for each item res/layout/singlelistitem:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/single_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:padding="5dp"
android:background="#206">
</TextView>
and the code I use to populate it:
private ListView playlistView;
private void buildPlaylistView() {
playlistView = (ListView)findViewById(R.id.playlistview);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.singlelistitem, R.id.single_item, playlist.titlesAsArray());
playlistView.setAdapter(adapter);
playlistView.setVisibility(View.VISIBLE);
adapter.notifyDataSetChanged();
((ArrayAdapter<String>)playlistView.getAdapter()).notifyDataSetChanged();
}
playlist.titlesAsArray() does return String[] and it works.
I have both of the .notifyDataSetChanged() in there, since I found that on SO and gave it a try.
When I change the android:layout_height in the ListView object in my XML to wrap_content, I see only the opaque background that is in the LinearLayout that wraps it. When I set the ListView android:layout_height to match_parent, the whole screen is #206 (magentish).
When i check getCount() on the adapter before setAdapter() it says there are items. When I check it after, from the view itself, it says there are the same number of items. I'm totally lost on this one, but nothing is displayed.
Try changing from android:orientation="horizontal" to android:orientation="vertical" this may fix.
I have a listview in my scroll view underneath almost a page worth of scroll before that but once my listview gets populated the scrollview moves to the top of the list view. how can I fix this/prevent this from happening?
SCROLL VIEW XML:
<ScrollView
android:id="#+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
layout="#layout/a" />
<include
layout="#layout/b" />
<include
layout="#layout/c" />
<include
layout="#layout/d" />
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
I've tried doing
sv.fullScroll(ScrollView.FOCUS_UP);
and all that stuff to my scrollview but it doesnt work
We should never put a ListView inside a ScrollView.
Work Around : When ScrollView moves up/down because of listview's notifyDataSetChanged(),
Then try,
scrollview.setEnabled(false);
listview.setFocusable(false);
adapter.notifyDataSetChanged();
scrollview.setEnabled(true);
Firstly, probably you've already heard about it, but just in case: You should never put a ListView inside a ScrollView, as ListView itself already has got a ScrollView and this design goes against the whole ListView idea. If you're convinced you have to use it, probably there's a better approach to use and you may need to simplify your code somehow.
Now, even if you still want to use something like that, you may use something like this:
package your.package.name;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
public class ScrollingListView {
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
}
You simply set your adapter via .setAdapter() and afterwards call ScrollingListView.setListViewHeightBasedOnChildren(your_listview). This should redimension your window accordingly to your ListView height.
---- EDIT ----
That will be probably the ugliest workaround, but try doing the following:
ScrollView sv = (ScrollView) findViewById(R.id.your_scrollview);
sv.setEnabled(false);
// Populate your ListView
sv.setEnabled(true);
Add all the stuff on top as header to the list view.
Now that I see the code.. you can only have one ViewGroup inside a scrollview. So you would warp the two layouts into another one, BUT a ListView automatically has a scroll view in it so that wont really work.
So what you have to do is use the addHeader view in your ListActivity (of fragment) and inflate LinearLayout1 in the activity from a different xml file.
add:
android:transcriptMode="disabled"
in the list you don't want to scroll
From Android Docs
It's not possible to make a scrollable view inside a scrollable view. But as a work around this, and only in case that this listviews doesn't take much memory if all views are loaded. you can use this
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
public class NonScrollableListView extends ListView {
public NonScrollableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Do not use the highest two bits of Integer.MAX_VALUE because they are
// reserved for the MeasureSpec mode
int heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightSpec);
getLayoutParams().height = getMeasuredHeight();
}
}
Again, it's not good to use this workaround
Just Do one thing before add items in your list
listview.setFocusable(false);
after that you can again do that
listview.setFocusable(true);
if needed it will work for sure
I would wrap the list and the other layouts in a RelativeLayout instead of a LinearLayout
<ScrollView
android:id="#+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<RelativeLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<include
layout="#layout/a" />
<include
layout="#layout/b" />
<include
layout="#layout/c" />
<include
layout="#layout/d" />
</LinearLayout>
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/container" />
</RelativeLayout>
</ScrollView>
This way the top border of the ListView is boun to the bottom border of the LinearLayout and will always stay under everything else.
You cant put the includes directly in the RelativeLayout! See here for more details.
I have made 2 or 3 changes in your xml file
<ScrollView
android:id="#+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"> // This will let you see the scroll bar of list view
when you scroll your list view.
<include
layout="#layout/a" />
<include
layout="#layout/b" />
<include
layout="#layout/c" />
<include
layout="#layout/d" />
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="300dp" />// Instead of wraping up your list, if you wish
you can give certain height to your list view.
</LinearLayout>
</ScrollView>
Another thing you need is write the given code in your java file.
onCreate()
{
....
ScrollView sView=(ScrollView)findViewById(R.id.tvscrollview);
yourListView.setOnTouchListener(new OnTouchListener()
{
public boolean onTouch(View arg0, MotionEvent arg1)
{
if(arg1.getAction() == MotionEvent.ACTION_DOWN || arg1.getAction() == MotionEvent.ACTION_MOVE)
{
sView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});
I hope this helps you.
You may want to achieve this by using following:
<LinearLayout
......>
<ScrollView
android:id="#+id/tvscrollview"
android:layout_marginTop="8.0dip"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
layout="#layout/a" />
<include
layout="#layout/b" />
<include
layout="#layout/c" />
<include
layout="#layout/d" />
</LinearLayout>
</ScrollView>
<ListView
android:id="#+id/listview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Wrap your listview outside scrollview and else inside scrollview, because You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
Source Android Docs
The only solution that worked for me was to add an EditText as the first child of the layout. Ugly, I know.
<EditText
android:layout_width="0dp"
android:layout_height="0dp" />
I had the same issue I found the solution by changing the visibility of the list view in XML after setting the adapter I change the visibility to visible
listView.setAdapter(adapter);
listView.setVisibility(View.VISIBLE);
Though its a very late answer to this question and this answer has already an accepted answer, I thought putting how I solved my problem here might help others to find everything related to this problem in a single SO thread.
So here's my situation: I had a ScrollView with a ListView at the end of the layout. I know its a very bad practice to do so. I could achieve the same behaviour I wanted by attaching a header to the ListView. But anyway, my ListView got the focus when it was populated with the data and the the page was scrolled automatically to the bottom where the ListView started.
I tried with the accepted answer here, but it didn't work for me. I tried using a dummy EditText at the top of the layout so that it could request the focus automatically, but it didn't work either. Because the ListView was getting the focus after the data is loaded from a REST Api call.
Then I found this answer and this really helped. So I thought putting it in here so that others might get help from a single thread having the same problem like me.
mainScrollView.fullScroll(ScrollView.FOCUS_UP); didn't work for me either as the list was populated after the other views were populated. So I had to scroll the ScrollView to the top after the ListView is populated. So here's how I solved my problem.
mScrollView.setEnabled(false);
mIntroducerListView.setFocusable(false);
mListAdapter.notifyDataSetChanged();
// Force scroll to the top of the scroll view.
// Because, when the list view gets loaded it focuses the list view
// automatically at the bottom of this page.
mScrollView.smoothScrollTo(0, 0);
I tried the above answers, but neither of them worked. Below is my final solution.
Just override the onFinishInflate method, then do a post to scrollTo(0, 0).
#Override
protected void onFinishInflate() {
super.onFinishInflate();
this.post(new Runnable() {
#Override
public void run() {
scrollTo(0, 0);
}
});
}
ListView
[Text] [Button 1][Button 2]
[Text] [Button 1][Button 2]
... (and so on) ...
Button 1 should be like Check Box and other button which allows to redirect on other page
Is above mentioned thing possible??
Thanks in advance..
Each row in a list view can have anything your heart desires. A row is basically defined as its own layout, and you can define the layout as you wish. In your case, you probably want to do a RelativeLayout. Check out the examples, they come pretty close to what you want.
You can have your ListView row to contain a CheckedTextView and a Button ina Linear Layout.
In \layout\ folder, define your customised my_row.xml, roughly so
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<CheckedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Then for populating your ListView, give this in your Adapter.
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, R.layout.my_row, strings);
myList.setAdapter(myAdapter);