I want to display a custom view, composed of a TextView above an ImageView in a vertical LinearLayout, one at a time in a Gallery.
The problem is that my custom view does not fill the screen. I can see a part of the other views on the sides and I don't want this issue.
Here is the xml of my custom view : gallery_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gallery_item_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/gallery_item_cardname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20dp"
android:textStyle="bold"
android:text="#string/contrebandiers_lvl1"
android:textColor="#android:color/darker_gray"
/>
<ImageView
android:id="#+id/gallery_item_cardimg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:contentDescription="#string/app_name"
android:src="#drawable/contrebandiers_lvl1"
/>
</LinearLayout>
Here is the code of the method getVew of my adapter : GTRoundDeckAdapter
public View getView(int position, View convertView, ViewGroup parent)
{
GalleryItem galleryItem;
if(convertView == null)
{
galleryItem = new GalleryItem();
convertView = mInflater.inflate(R.layout.gallery_item, null);
galleryItem.cardName = (TextView) convertView.findViewById(R.id.gallery_item_cardname);
galleryItem.cardImg = (ImageView) convertView.findViewById(R.id.gallery_item_cardimg);
convertView.setTag(galleryItem);
}
else
{
galleryItem = (GalleryItem) convertView.getTag();
}
GTCard gtCard = (GTCard) mRoundDeck.get(position);
galleryItem.cardName.setText(gtCard.getNameId());
galleryItem.cardImg.setImageResource(gtCard.getImgId());
return convertView;
}
I thank you for your help.
Samuel
I would recommend that you use the ViewPager instead of Gallery. In my personal experience, I have found Gallery to slightly buggy. If your requirement is to show only one View at a time, then ViewPager (which lets you swipe left and right to go one by one) should suit your needs.
You will need to include the Android Support package to use ViewPager.
Link to support package: http://developer.android.com/sdk/compatibility-library.html
Link on how to use ViewPager: http://blog.stylingandroid.com/archives/537
you should use both the width of textview and imageview fillparent.then it will be fill the screen of the gallery...
Related
I have a problem in my application Life Gallery. In this application, I have a fragment that displays the user's media directory in a gridView. Here is a screenshot :
As you can see, each directory is represented with an ImageView and a TextView, this latter containing the name of the directory. If you check the third line, you will see that the text of two TextView are empty...This is my bug. The elements of my gridview that present such a bug varies if I scroll or if rotate my phone...
Here is my layout for an element of the gridView :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_global"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="1dp" >
<ImageView
android:id="#+id/directory_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/content_description_album_imageview" />
<TextView
android:id="#+id/directory_text"
style="#style/Act_MyOwnLife_TextView_large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/directory_image"
android:background="#color/black_transparent"
android:gravity="right"
android:paddingRight="4dp"
android:singleLine="true"
/>
</RelativeLayout>
And here is the code for my Adapter, focusing on the function getView:
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder viewHolder = null;
if (view == null) {
LayoutInflater inflater = this.activity.getLayoutInflater();
view = inflater.inflate(R.layout.fragment_directory_gridview, parent, false);
viewHolder = new ViewHolder();
viewHolder.relativeLayout = (RelativeLayout)view.findViewById(R.id.layout_global);
viewHolder.textViewDirectory = (TextView) view.findViewById(R.id.directory_text);
viewHolder.imageViewDirectory = (ImageView) view.findViewById(R.id.directory_image);
view.setTag(R.id.viewHolder, viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag(R.id.viewHolder);
}
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
viewHolder.imageViewDirectory.setTag(position);
viewHolder.imageViewDirectory.setImageBitmap(null);
viewHolder.position = position;
ModelDirectoryAndMedia directoryAndImage =this.directoriesAndMedias.get(position);
viewHolder.textViewDirectory.setText(directoryAndImage.directoryView);
ImageView imageView = viewHolder.imageViewDirectory;
// creation/retrieve the thumbnail with a thread
job = new Job(imageView,
directoryAndImage.media, Options.OPTIONS_THUMBNAIL,
position);
this.bitmapCreate.addJobThumbnail(job);
return view;
}
What I did to find the bug :
I check that my String was not empty when I call "viewHolder.textViewDirectory.setText(s);"
I try to check with hierarchyViewer, but I can not browse an element if the TextView is empty...I do not know why...
I remove the transparency of the background, remove the background property of the textView, I set "ImageView.setImageBitmap(null);" to check that it was not due to the ImageView...
But without success...the bug was still here...
After more test, I found the reason of the bug: it is due to this line of code in the getView method :
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
I use this line to display the empty ImageView to the correct size. So that when the thumbnail is ready, the insertion in the ImageView will not change its size ( the settings of my LayoutParams is done with the size of my thumbnail )
Any idea ? any comments on my code ?
Thanks a lot !
Ok...The bug was due to the call to :
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
But I do not understand why...anyway, I did this to ensure that my ImageView had the correct initial size to display the thumbnail, loaded by a thread.
So I found an other solution to set a minimum size to the ImageView even if they are empty :
viewHolder.imageView.setMinimumHeight(this.viewControlerAlbum.sizeThumbnail);
viewHolder.imageView.setMinimumWidth(this.viewControlerAlbum.sizeThumbnail);
My layout.xml file is a bit updated :
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/content_description_album_imageview"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>
I added the adjustViewBounds attribute.
I'm having a slightly weird error here on my adapter.
The view the adapter is creating is a thumbnail on the left side and a table with a few rows. Each row have two textviews.
One of the textviews have the android:autoLink="web" property set and the listview have an onItemClickListener on it.
the problem is that every time a TextView auto-links it's content, next time its parent view is converted, it doesn't receive clicks from the onItemClickListener anymore.
Let me clarify with an example:
view1, view2, view3 and view4 are on the list view on the screen.
view2 have a link and it appears, and onClick the link opens.
the item click works normally for view1, view 3 and view4.
scroll the listview and view1 is converted to position5 and then view2 is converted to position6.
the item at position6 does not contain a link, but the onItemClick is also not fired for the position6 element.
the autolink feature of the textview is certainly changing something with my layout, but I don't know what. There must a property I can reset for every call to getView on my adapter, but which?
thanks for any help.
edit
let's see some code, it's pretty standard/good practices.
the getView from my adapter is:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Inflate a new layout if needed
if (convertView == null)
convertView = createNewView();
// Gets the item from my array
AGplus item = (AGplus) getItem(position);
// Gets the holder pointing to the views
Holder h = (Holder) convertView.getTag();
// That's a test version, I won't be using date.toString() later on
h.date.setText(new Date(item.getDate()).toString());
// This guys is giving me a headache,
// If it parses the link, I can't never click on this convertView anymore,
// event re-converting them for a text that does not contain links
h.txt.setText(item.getTitle());
// some image download stuff that doesn't matter for this code
return convertView;
}
that layouts used is a image and table and the amount of rows I inflate and insert on the table varies for each adapter. The table layout is a horizontal linear layout with a imageview and the table layout with some margin stuff and here is the row layout:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text" />
</TableRow>
if I completely remove the android:autoLink="web" I get all the clicks, but as stated before, once a view gets "auto-linked" and then I recycle that view, I can't get clicks on that view again.
edit
and here is the layout inflation:
private View createNewView() {
// Instantiate view
View v = getLayoutInflater().inflate(R.layout.expandable_child_view, null);
TableLayout table = (TableLayout) v.findViewById(R.id.table);
Holder h = new Holder();
v.setTag(h);
// Instantiate rows
h.thumb = (ImageView) v.findViewById(R.id.img);
h.date = (TextView) createNewRow(table, "Date: ");
h.txt = (TextView) createNewRow(table, "Text: ");
return v;
}
private View createNewRow(ViewGroup group, String title) {
View row;
row = getLayoutInflater().inflate(R.layout.item_table_row, null);
((TextView) row.findViewById(R.id.title)).setText(title);
group.addView(row);
return row.findViewById(R.id.text);
}
and before someone else asks, that's the expandable_child_view layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical" >
<ImageView
android:id="#+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="5dp"
android:layout_marginTop="20dp"
android:src="#drawable/ic_launcher" />
<TableLayout
android:id="#+id/table"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</TableLayout>
</LinearLayout>
as I said before, just a linear layout with a imageview and a table and a few margins.
According to Romain Guy here, this is done by design to support trackball/dpad navigation. Comment 27 has a workaround to it, by setting descendant focusability on each listview item:
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
or
android:descendantFocusability="blocksDescendants"
I think I know what may be going on. When you do setText(), sometimes it'll wipe out a lot of stuff. You may have to use a ClickableSpan to put the link action back into the textview.
I am not quite sure my question really has something to do with listview.There is an app named Gleeo Time Tracker ,and here has a screenview of it.When you press the symbol "+",a new item will be created,and you can delete one item by pressing the "-".More is that when I click the record button on the left of the item,the background will change.
My question is,what is it in the end,a listview? How can I achieve such thing?Thank you all!
What you want to do, is build a custom ListView.
This is done by providing a layout file, for example
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#android:color/transparent">
<ImageView android:id="#+id/Plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
<TextView android:id="#+id/Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent" />
</LinearLayout>
This layout is then applied to each row of your ListView by overriding its Adapter's getView() method, for example something like this:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) MyActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.row, null);
}
ImageView plus = (ImageView) v.findViewById(R.id.plus);
icon.setImageDrawable(BrowseActivity.this.getResources().getDrawable(R.drawable.plus));
TextView title = (TextView) v.findViewById (R.id.Browse_FileName);
// add a listener to your button and you're done
return v;
}
read about list view in developer docs and here is an example
I'm having a weird problem, in my rather complex view layout. (I will try to simplify it a bit in my explanation)
Basically I have a ListView, where each item consists of a TextView and an ImageButton. I am able to either click the list item (on the textview), or the button (I set the ImageButton to non-focusable, otherwise it wouldn't work)
Now it seems to work fine, until I open another window and return to the listview.
From that point on, I can click the ImageButton without anything happening (not even the background changes during the click). But when I click on the TextView again, all the click events from the ImageButton are dispatched at once.
Why is that?
EDIT:
The List Item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="0px"
android:minHeight="40dp"
android:orientation="horizontal"
android:paddingLeft="2px"
android:paddingRight="2px"
>
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Text"
android:textSize="19dp"
android:paddingTop="4px"
android:paddingBottom="4px"
android:layout_gravity="center_vertical"/>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/open_subtree_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="0px"
android:orientation="horizontal"
android:padding="0px">
<View
android:layout_width="1px"
android:layout_height="match_parent"
android:background="#drawable/separator_line" />
<com.treeviewer.leveldisplay.DontPressWithParentImageButton
android:id="#+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:background="#drawable/list_selector_background"
android:focusable="false"
android:focusableInTouchMode="false"
android:padding="10dp"
android:src="#drawable/arrow_right" />
</LinearLayout>
</LinearLayout>
That's how it is inflated:
[...]
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = inflater.inflate(R.layout.tree_row, null, false);
TextView textView = (TextView)mView.findViewById(R.id.text1);
LinearLayout nextNodeButtonContainer = (LinearLayout)mView.findViewById(R.id.open_subtree_layout);
if(childCount >= 0) {
titleBuilder.append(" (" + childCount + ")");
nextNodeButtonContainer.setVisibility(View.VISIBLE);
View button = nextNodeButtonContainer.findViewById(R.id.btn_right);
button.setFocusable(false);
button.setFocusableInTouchMode(false);
//button.setClickable(true);
button.setOnClickListener(clickListener);
button.setTag(tagValue);
} else {
nextNodeButtonContainer.setVisibility(View.GONE);
}
textView.setText(titleBuilder);
Let me know, if you need more code.
Ok, I finally solved this problem.
Unfortunately, in my question I didn't provide the necessary information to solve it, as the problem was somewhere I didn't expect it:
I have a ListAdapter where the getView method looks like this:
public View getView(int position, View convertView, ViewGroup parent) {
return mNodes.get(position).getView(mNodeArrowClickListener, position);
}
And the getView method of the nodes (TreeLevelElements) looked like:
public class TreeLevelElement {
private final Context mContext;
private View mView = null;
//[...] other methods
View getView(OnClickListener clickListener, final int tagValue) {
if(mView == null) {
//[...] produce a new View from XML
}
return mView;
}
}
The problem was, that I stored the Views in my elements, so I guess that conflicted somehow with android strategy to reuse old views for new items.
I don't know what exactly happened, but now that I removed mView and create a new one every time, it works.
I will also change it to reuse the convertView instead.
a designer made some design for my Android app, here is a design for a ListView (not the real one but the same idea..):
So in the middle of the green area there is some text, and in the orange area an imageview (clickable..), and in the middle of the blue area another text.. this is 1 listview.. so if you swipe one row the other also swipe the same.. (they arent 3 listviews..) The yellow area is empty
How do I align the views so it works on all screen sizes? How can I center the text in the green and blue area?
Thanks
Here is the xml of the row I used:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="horizontal"
android:layout_height="wrap_content" android:paddingLeft="40dip"
android:paddingRight="40dip">
<TextView android:id="#+id/Start_Numbering" android:textSize="19.5sp"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_weight="0.3"
/>
<ImageView android:id="#+id/Start_ImageView"
android:layout_weight="0.1" android:layout_height="wrap_content"
android:layout_width="fill_parent" android:src="#drawable/list_noaudioavailable"
></ImageView>
<TextView android:id="#+id/Start_Name" android:textColor="#a7e9fe"
android:textSize="21dip" android:layout_width="fill_parent"
android:layout_weight="0.6"
android:layout_height="wrap_content" />
Here is getView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = mInflater.inflate(R.layout.start_row, null); //line 47
holder=new ViewHolder();
holder.tv_Name =(TextView)convertView.findViewById(R.id.Start_Name);
holder.tv_PageNumber = (TextView)convertView.findViewById(R.id.Start_Numbering);
holder.im_Audio=(ImageView)convertView.findViewById(R.id.Start_ImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_Name.setText(Names[position]);
holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));
return convertView;
}
class ViewHolder {
TextView tv_Name;
TextView tv_PageNumber;
ImageView im_Audio;
}
But all I get is this, why the tv_Name isnt being display?:
Omar, your questions wasn't crystal clear, but I will give it a shot.
You use
In your row.xml, you would use
LinearLayout as the parent with orientation as horizontal
It will have five child elements
a. Yellow View with layout_weight=2
b. Blue TextField with layout_weight=5
c. Orange ImageField with layout_weight=3
d.
Green TextField with layout_weight=4
e. Yellow View with
layout_weight=1
For centering the text use appropriate text align property. All of these elements should have layout_width defined as fill_parent.