set Image View height and width in Grid View - android

i want to create a image gallery in my app
i use grid view to display images , but images displaying Messed up
how i can display images equal ?such as other image gallery app
layout file :
<GridView
android:id="#+id/galleryGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="3"
android:rowCount="3"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp" />
java file:
public class GalleryManager extends BaseAdapter {
Context context;
List<Drawable> list;
public GalleryManager(Context context , List<Drawable> list ) {
this.context = context;
//this.list = list;
this.list = list;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
ImageView imageView = new ImageView(context);
imageView.setImageDrawable(list.get(position));
imageView.setScaleType(ImageView.ScaleType.CENTER);
return imageView;
}
catch(Exception e){
Log.i("Tag", "getView: "+e.toString());
}
return null;
}
}

Try
public class MyImageView extends android.support.v7.widget.AppCompatImageView {
public MyImageView(Context context) {
super(context);
}
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int size = getContext().getResources().getDimensionPixelSize(R.dimen.space);
setMeasuredDimension(size, size);
}
}
in dimen.xml
<dimen name="space">100dp</dimen>
And
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
MyImageView imageView = new MyImageView(context);
imageView.setImageDrawable(list.get(position));
imageView.setScaleType(ImageView.ScaleType.CENTER);
return imageView;
}
catch(Exception e){
Log.i("Tag", "getView: "+e.toString());
}
return null;
}
}

Try setting the image weight to 1 in your java code

Related

Custom layout for ListPreference

I am using PreferenceActivity for the setting of my app.
I want to add a new preference that allow the user to select an icon.
For this task I want to use a ListPreference, but I want also to show the icon in the list.
I tried to customize the ListPreference to use a custom layout, but the problem is that once I do that the list items are not clickable (it does show my custom layout and use the default value for the current selection).
I tested it on different emulator version and on Galaxy S2. When pressing the item I could see some effect of the pressed/unpressed, but the onClick method is not called.
I followed the instruction on Android: Checkable Linear Layout for adding custom layout (I also tried the option describe in How to customize list preference radio button, but the same result).
IconTypePreference.java (copied from ListPreference and modified):
public class IconTypePreference extends DialogPreference {
private IconType value;
private int clickedDialogIndex;
private boolean valueSet;
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public IconTypePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public IconTypePreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public IconTypePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public IconTypePreference(Context context) {
super(context);
}
public void setValue(String value) {
// Always persist/notify the first time.
final boolean changed = !TextUtils.equals(getValueText(), value);
if (changed || !valueSet) {
if (value == null) {
this.value = null;
} else {
this.value = IconType.valueOf(value);
}
valueSet = true;
persistString(value);
if (changed) {
notifyChanged();
}
}
}
public void setValueIndex(int index) {
setValue(IconType.values()[index].toString());
}
public IconType getValue() {
return value;
}
public String getValueText() {
return (value == null ? null : value.toString());
}
public int findIndexOfValue(String value) {
IconType[] values = IconType.values();
for (int i = values.length - 1; i >= 0; i--) {
if (values[i].toString().equals(value)) {
return i;
}
}
return -1;
}
private int getValueIndex() {
return findIndexOfValue(getValueText());
}
#Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
clickedDialogIndex = getValueIndex();
builder.setSingleChoiceItems(new IconTypeAdapter(getContext()), clickedDialogIndex,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
clickedDialogIndex = which;
IconTypePreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
});
/*
* The typical interaction for list-based dialogs is to have
* click-on-an-item dismiss the dialog instead of the user having to
* press 'Ok'.
*/
builder.setPositiveButton(null, null);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult && clickedDialogIndex >= 0) {
String value = IconType.values()[clickedDialogIndex].toString();
if (callChangeListener(value)) {
setValue(value);
}
}
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
#Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedString(getValueText()) : (String)defaultValue);
}
#Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = getValueText();
return myState;
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState)state;
super.onRestoreInstanceState(myState.getSuperState());
setValue(myState.value);
}
private static class SavedState extends BaseSavedState {
String value;
public SavedState(Parcel source) {
super(source);
value = source.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(value);
}
public SavedState(Parcelable superState) {
super(superState);
}
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
private static class IconTypeAdapter extends ArrayAdapter<IconType> {
private final String[] iconTypeText;
private LayoutInflater inflater;
public IconTypeAdapter(Context context) {
super(context, R.layout.icon_type_item, IconType.values());
this.inflater = LayoutInflater.from(context);
iconTypeText = context.getResources().getStringArray(R.array.icon_type);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.icon_type_item, parent, false);
}
((TextView)convertView.findViewById(R.id.text)).setText(iconTypeText[position]);
convertView.setClickable(true);
// todo: set view text
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public long getItemId(int position) {
return position;
}
}
}
CheckableLinearLayout.java
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private Checkable checkable;
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
// setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
checkable = getCheckable(this);
if (checkable == null) {
throw new RuntimeException("Missing Checkable component");
}
}
private Checkable getCheckable(ViewGroup viewGroup) {
View v;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; ++i) {
v = getChildAt(i);
if (v instanceof Checkable) {
return (Checkable)v;
} else if (v instanceof ViewGroup) {
Checkable result = getCheckable((ViewGroup)v);
if (result != null) {
return result;
}
}
}
return null;
}
#Override
public void setChecked(boolean checked) {
checkable.setChecked(checked);
}
#Override
public boolean isChecked() {
return checkable.isChecked();
}
#Override
public void toggle() {
checkable.toggle();
}
}
icon_type_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.utils.ui.widget.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView android:id="#+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="false"
android:focusableInTouchMode="false"/>
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"/>
</com.utils.ui.widget.CheckableLinearLayout>
Added to settings.xml
<com.utils.ui.preference.IconTypePreference
android:key="icon_type"
android:defaultValue="type_b"
android:title="#string/icon_type_preference_title"/>
EDIT
There is a bug in CheckableLinearLayout.java
Replace the getCheckable method with this:
private Checkable getCheckable(ViewGroup viewGroup) {
View v;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; ++i) {
v = viewGroup.getChildAt(i);
if (v instanceof Checkable) {
return (Checkable)v;
} else if (v instanceof ViewGroup) {
Checkable result = getCheckable((ViewGroup)v);
if (result != null) {
return result;
}
}
}
return null;
}
Found the solution to the problem.
The problem was in the getView method of the adapter:
I changed
convertView.setClickable(true);
to
convertView.setClickable(false);

Adding a Custom View as header of ListView

I have a custom view (a class extending View) that I'd like to add as a header of List View. Here's the code snippet:
public class MyActivity extends RoboListActivity {
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View header = getLayoutInflater().inflate(R.layout.myactivity_apps_header, null);
getListView().addHeaderView(header);
...more code
}
But, I can't see anything. But, when I tried to add a non-custom view, it works. Am I missing something, please guide
Providing Complete Source Code
Custom View
public class SpaceCustomView extends View {
private Paint mPaint;
private Paint mTextPaint;
private final String mMessage = "Foo Bar";
private Rect mBounds;
public StorageSpaceCustomView(Context context) {
super(context);
initInput();
}
public StorageSpaceCustomView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initInput();
}
public StorageSpaceCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initInput();
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
#Override
public void onDraw(android.graphics.Canvas canvas) {
canvas.drawRect(30, 30, 800, 80, mPaint);
canvas.drawText(mMessage, 30, 60, mTextPaint);
}
private void initInput() {
mBounds = new Rect();
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mTextPaint = new Paint();
mTextPaint.setColor(Color.BLACK);
mTextPaint.setTextAlign(Paint.Align.LEFT);
mTextPaint.setTextSize(20);
mTextPaint.getTextBounds(mMessage, 0, mMessage.length(), mBounds);
}
}
Header Layout XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.mycompany.app.view.custom.SpaceCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Activity Class
public class AppsActivity extends RoboListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//add header and footer views
View header = getLayoutInflater().inflate(R.layout.activity_apps_header, null);
getListView().addHeaderView(header);
View footer = getLayoutInflater().inflate(R.layout.activity_pps_footer, null);
getListView().addFooterView(footer);
List<AppInfo> applicationList = Mycatalog.getPromotions();
AppListAdapter adapter = new AppListAdapter(this, applicationList);
setListAdapter(adapter);
}
private class AppListAdapter extends ArrayAdapter<AppInfo> {
public AppListAdapter(Activity activity, List<AppInfo> apps) {
super(activity, android.R.layout.simple_list_item_1, apps);
}
#Override
public boolean isEmpty(){
return false;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// if we weren't given a view, inflate one
if (null == convertView) {
convertView = getLayoutInflater()
.inflate(R.layout.activity_uninstall_apps, null);
}
return convertView;
}
}
}
Conclusion: I can see the footer but not the header.
ListView shows headers and footers only when it's Adapter's isEmpty() returns false.
So try setting an adapter that does that...

Updating Layout of a row in ListView when OnClick event is called

I have a ListView in which there is a TextView and a custom view in which I am drawing a rectangle. I want a functionality that when a row of ListView is clicked, the rectangle should become bigger but other row's rectangle should remain in its previous shape.
So first I am increasing width and height of layout and then trying to increase the rectangle size after that but although my onDraw() method is called when I am clicking the listener but size of rectangle is not increasing.
Also my onDraw() method of DrawView is called infinitely even though I am clicking only once
Can anyone help me out.
DrawView.java, which is used for making making rectangle
public class DrawView extends View {
Paint paint = new Paint();
public int x=-1; // this variable will tell
public DrawView(Context context) {
this(context, null);
}
public DrawView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onDraw(Canvas canvas) {
paint.setStrokeWidth(10);
paint.setColor(Color.MAGENTA);
Log.e("Ronak","onDraw "+x);
canvas.drawRect(0, 0, 300, 200, paint );
if(x>=0) //this method is not called for first view but is called for onClickListener
{
increase(canvas);
}
}
private void increase(Canvas canvas) {
Log.e("Ronak","Increase");
canvas.drawRect(0, 0, 700, 800, paint );
}
}
My getView() function for custom ListView
public View getView(final int position, View convertView, final ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.news_list_item,null);
final LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.mainLayout);
TextView t= (TextView)convertView.findViewById(R.id.textView1);
holder.textview = t;
holder.ll=layout;
final DrawView abc = (DrawView)convertView.findViewById(R.id.drawview);
holder.drawview=abc;
Log.e("Ronak","reached here3");
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textview.setText(mData.get(position));
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(c, "Clicked on="+position, 2).show();
ViewHolder mH = (ViewHolder) v.getTag();
LinearLayout.LayoutParams pp = new LinearLayout.LayoutParams(500,400);
mH.ll.setLayoutParams(pp);
DrawView dd=mH.drawview;
dd.x=position;
dd.invalidate();
}
});
return convertView;
}
static class ViewHolder {
public DrawView drawview;
public TextView textview;
public LinearLayout ll;
}
and my layout file for each row of ListView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="2dp" >
<TextView
android:id="#+id/textView1"
android:layout_width="50dp"
android:layout_height="30dp"
android:text="Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<com.krish.horizontalscrollview.DrawView
android:id="#+id/drawview"
android:layout_width="150dp"
android:layout_height="100dp" >
</com.krish.horizontalscrollview.DrawView>
</LinearLayout>
My ListView class
public class CenterLockHorizontalScrollview extends HorizontalScrollView {
Context context;
int prevIndex = 0;
public CenterLockHorizontalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.setSmoothScrollingEnabled(true);
}
public void setAdapter(Context context, CustomListAdapter mAdapter) {
try {
fillViewWithAdapter(mAdapter);
} catch (ZeroChildException e) {
e.printStackTrace();
}
}
private void fillViewWithAdapter(CustomListAdapter mAdapter)
throws ZeroChildException {
if (getChildCount() == 0) {
throw new ZeroChildException(
"CenterLockHorizontalScrollView must have one child");
}
if (getChildCount() == 0 || mAdapter == null)
return;
ViewGroup parent = (ViewGroup) getChildAt(0);
//parent.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
parent.addView(mAdapter.getView(i, null, parent));
}
}
I suppose you store a String list in mData. Make a class with members mData and mIsSelected (boolean) and pass an object of this class in the adapter. In onClick() check whether the row is already selected, invert the value of mIsSelected and perform the required operation at end call notifyDataSetChanged()

get GridView Item exactly square

I am using a grid view to show my data [i.e. A image and its tiltle]
And my image is loaded dynamically with my imageloader library. The issue is some of my images are in landscape or portrait. And due to this my grid element dont maintain exact square ratio. Some are vertically stretch or compressed other wise.
<GridView
android:id="#+id/fcpl_grid_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:scrollingCache="false"/>
Here is my getView method:
public View getView(final int position, View convertView, final ViewGroup parent) {
final ViewHolder viewholder;
Log.e("Calling...","getView");
if (convertView == null) {
convertView = inflater.inflate(R.layout.inflater_product_list, parent, false);
viewholder = new ViewHolder();
viewholder.productImage = (ImageView) convertView.findViewById(R.id.ipl_imageview);
viewholder.backGroundLayout = (RelativeLayout) convertView.findViewById(R.id.ipl_bk_layout);
viewholder.productName = (TextView) convertView.findViewById(R.id.ipl_productname);
convertView.setTag(viewholder);
} else {
viewholder = (ViewHolder) convertView.getTag();
}
viewholder.productName.setText("SOME TEXT");
String imageUrl = "SOME URL";
imageLoader.get(imageUrl, VALUES_FOR_MY_IMAGE_LOADER_LIBRARY));
return convertView;
}
I tried different suggested method online but none work as i have dynamic image loading and the imageView layoutParams are not known when the getView is called.
I suggest you to make class that extends ImageView (or GridView) and measure bounds of root or any other parent view. Then just use it in your item xml.
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
View rootView = this.getRootView();
if (rootView != null) {
width = rootView.getWidth();
height = rootView.getHeight();
}
int size = width > height ? height : width;
super.onMeasure(size, size);
setMeasuredDimension(size, size);
}
}

Filling 4 Items in a listview on any device

I'm developing an application that have to show exactly 4 items at a time in a listview, independent of device.
How do I get the size of the list view on the device and set list items height to fit 4 at a time on the screen?
1- extend ListView class
public class CustomListView extends ListView {
public CustomListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomListView(Context context) {
super(context);
}
private Runnable afterLayoutRunnable;
public void setAfterLayoutRunnable(Runnable afterLayoutRunnable) {
this.afterLayoutRunnable = afterLayoutRunnable;
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (afterLayoutRunnable != null) {
afterLayoutRunnable.run();
}
}
}
2- create your own ArrayAdapter
public class CustomListAdapter extends ArrayAdapter<MyObject> {
public CustomListAdapter(Context context, int textViewResourceId, List<MyObject> objects) {
super(context, textViewResourceId, objects);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.my_item_layout, null);
int height = TestActivity.listItemsMinimumHieght;
if (height > 0) {
convertView.setMinimumHeight(height);
}
}
}
}
3- in your Activity
public class TestActivity extends Activity {
public static int listItemsMinimumHieght = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final CustomListView customListView = (CustomListView) findViewById(R.id.conversation_activity_button_send);
customListView.setAfterLayoutRunnable(new Runnable() {
#Override
public void run() {
listItemsMinimumHieght = customListView.getHeight() / 4;
ArrayList<MyObject> objects=getListContent();
customListView.setAdapter(new ListViewConversationAdapter(TestActivity.this, R.id.sample, objects));
}
});
}
}
i think this should work, good luck

Categories

Resources