get GridView Item exactly square - android

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);
}
}

Related

set Image View height and width in Grid View

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

Inisializing custom list view

i initialized Listview through XML :
<com.example.app.ListViewManage
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="45dp"
/>
and i couldn't manage initializing the list inside a class is there a way doing that ?
class code: im trying to set with init() function, and how could i pass values from another class if this class is passed to the XML?
public class ListViewManage extends ListView{
int HEADER_HEIGHT = 45;
int HeaderID = 0;
Context context = null;
int HeightInPixels = 0;
int WidthInPixels = 0;
float alphaScale = 0;
float PrevAlpha = 0;
public ListViewManage(Context context) {
super(context);
init(context);
}
public ListViewManage(Context context,AttributeSet attrs){
super(context, attrs);
}
public ListViewManage(Context context,AttributeSet attrs,int defStyle){
super(context, attrs,defStyle);
}
public void init(Context context){
this.context = context;
DisplayMetrics dm = context.getResources().getDisplayMetrics();
this.HeightInPixels = dm.heightPixels;
this.WidthInPixels = dm.widthPixels;
this.alphaScale = this.HEADER_HEIGHT/this.HeightInPixels;
FrameLayout.LayoutParams fl=(FrameLayout.LayoutParams)getLayoutParams();
fl.topMargin=HEADER_HEIGHT;
setLayoutParams(fl);
ArrayAdapter<YTFileDownload> ListAdapter = new ArrayAdapter<YTFileDownload>(context,R.layout.download_list_view,R.id.Title,YTDownloadsManage.Downloads){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = super.getView(position, convertView, parent);
ProgressBar bar =(ProgressBar)v.findViewById(R.id.Process);
bar.setProgress(0);
TextView tv = (TextView)v.findViewById(R.id.Title);
tv.setText(YTDownloadsManage.Downloads.get(position).getVideoID());
TextView tv2 = (TextView)v.findViewById(R.id.Speed);
tv2.setText("0MB");
return v;
}
};
LayoutInflater li=LayoutInflater.from(context);
this.setAdapter(ListAdapter);
}
}
ListViewManage mlv = (ListViewManage) findViewById(R.id.list);
mlv.setAdapter(adapter);
In your getView() method, i think you should missed:
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.custom_listview_item, null);
adapter.notifyDataSetChanged();

Android: Expandable List/Gridview causing never-ending loading

My app contains two ExpandableHeightListViews and one ExpandableHeightGridView with shared vertical scrolling.
The contents of the views are read in from a file. This works fine with small files, the data is displayed correctly and the activity loads.
However, when selecting large files, the activity never actually loads, when I debug it, the adapters for the three views are just looping round endlessly. I'm assuming this is due to the expanded nature of the views they are trying to load everything, but surely this can be avoided?
Here is the code ...
ExpandableHeightListView ...
public class ExpandableHeightListView extends ListView
{
boolean expanded = false;
public ExpandableHeightListView(Context context)
{
super(context);
}
public ExpandableHeightListView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightListView(Context context, AttributeSet attrs, int defaultStyle)
{
super(context, attrs, defaultStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
ExpandableHeightGridView ...
public class ExpandableHeightGridView extends GridView
{
boolean expanded = false;
public ExpandableHeightGridView(Context context)
{
super(context);
}
public ExpandableHeightGridView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightGridView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
MainActivity ...
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView (R.layout.activity_editor);
Intent intent = getIntent();
m_File = new File (intent.getStringExtra ("file_path"));
m_FileLength = (int) m_File.length();
// Account for non-complete line at end of file ...
if ((m_FileLength % 8) == 0)
m_NumLines = (m_FileLength / 8) + ADDITIONAL_LINES;
else
m_NumLines = (m_FileLength / 8) + ADDITIONAL_LINES + 1;
// Set up index ListView
m_IndexListView = (ExpandableHeightListView) findViewById (R.id.index_listview);
m_IndexAdapter = new IndexAdapter (getApplicationContext(), m_NumLines);
m_IndexListView.setAdapter (m_IndexAdapter);
m_IndexListView.setExpanded(true);
// File reader object for hex/ascii adapters ...
FileReader fileReader = new FileReader (getApplicationContext(), m_File);
// Set up hex GridView
m_HexGridView = (ExpandableHeightGridView) findViewById (R.id.hex_gridview);
m_HexAdapter = new HexAdapter (getApplicationContext(), fileReader);
m_HexGridView.setAdapter(m_HexAdapter);
m_HexGridView.setExpanded (true);
// Set up ascii ListView
m_AsciiListView = (ExpandableHeightListView) findViewById (R.id.ascii_listview);
m_AsciiAdapter = new AsciiAdapter (getApplicationContext(), m_NumLines, fileReader);
m_AsciiListView.setAdapter(m_AsciiAdapter);
m_AsciiListView.setExpanded (true);
m_HexGridView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
view.setSelected (true);
}
});
The three adapters simply read some data from the given file and display it accordingly.
Does anyone know how to fix this and make the adapter views only load the necessary part?
EDIT: Adapter code ...
HexAdapter ...
public class HexAdapter extends BaseAdapter
{
// CONSTANTS
// Number of additional blank lines to append ...
private final int ADDITIONAL_LINES = 30;
// VARIABLES
// Context of the EditorActivity ...
private Context m_Context;
// Reference to file being edited ...
private FileReader m_FileReader;
// Number of elements that are within file ...
private int m_FileLength;
// Number of total elements to produce ...
private int m_NumElements;
// FUNCTIONS
public HexAdapter (Context c, FileReader fileReader)
{
m_Context = c;
m_FileReader = fileReader;
m_FileLength = (int) m_FileReader.getLength();
int finishLine = 8 - (m_FileLength % 8);
m_NumElements = m_FileLength + finishLine + (ADDITIONAL_LINES * 8);
}
public int getCount()
{
return m_NumElements;
}
public Object getItem(int position)
{
return null;
}
public long getItemId(int position)
{
return 0;
}
// Create new TextView for each item referenced by the Adapter ...
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)
m_Context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View view;
if (null == convertView)
view = inflater.inflate (R.layout.editor_hex_element, parent, false);
else
view = convertView;
// Remove padding if rightmost element ...
LinearLayout container = (LinearLayout) view.findViewById (R.id.gridview_hex_container);
if ((position % 8) == 7)
container.setPadding (0,0,0,0);
else
container.setPadding (0,0,1,0);
String hexText;
// If position is within current file space, read from file ...
if (position < m_FileLength)
{
// Read from file and generate hexadecimal text
byte[] buffer = m_FileReader.ReadBytesFromFile(position, 1);
hexText = Integer.toHexString ((char)buffer[0]).toUpperCase();
// Prepend extra zero if length is 1 ...
if (hexText.length() == 1)
hexText = "0" + hexText;
}
else
{
// Set to default un-edited value (00) ...
hexText = "00";
}
// Get TextView instance and set text ...
TextView textView = (TextView) view.findViewById (R.id.gridview_hex_edit);
textView.setText (hexText);
// Set colour depending on file length ...
if (position < m_FileLength)
textView.setTextColor (m_Context.getResources ().getColor (R.color.DarkerAccentOrange));
else
textView.setTextColor (m_Context.getResources ().getColor (R.color.hex_gray));
return view;
}
// TODO: Add function to update file length and numElements variables
// public void UpdateFileLength (int numLength) ...
}
AsciiAdapter ...
public AsciiAdapter (Context c, int numLines, FileReader fileReader)
{
m_Context = c;
m_FileReader = fileReader;
m_NumLines = numLines;
m_FileLength = (int) fileReader.getLength();
}
public int getCount()
{
return m_NumLines;
}
public Object getItem(int position)
{
return null;
}
public long getItemId(int position)
{
return 0;
}
// Create new TextView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)
m_Context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
View view;
if (null == convertView)
view = inflater.inflate (R.layout.editor_ascii_element, parent, false);
else
view = convertView;
final int readPosition = position * BYTE_SIZE;
final int fileRemaining = m_FileLength - readPosition;
final int readLength = (fileRemaining >= BYTE_SIZE) ? BYTE_SIZE : fileRemaining;
byte[] buffer;
StringBuilder builder = new StringBuilder ();
// If some of file remaining, read ...
if (readLength > 0)
{
buffer = m_FileReader.ReadBytesFromFile (readPosition, readLength);
// Build read string ...
for (byte b : buffer)
builder.append (convertByte (b));
}
// Append remaining part of string (not read from file) ...
final int remaining = (readLength > 0) ? (BYTE_SIZE - readLength) : BYTE_SIZE;
for (int k = 0; k < remaining; k++)
builder.append ('.');
TextView textView = (TextView) view.findViewById (R.id.ascii_textview);
textView.setText (builder.toString());
return view;
}
}

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()

Inflating a custom layout view into a Layout extending class in Android

I have a custom layout defined in XML file which has a RelativeLayout root with a bunch of child view.
Now, I defined the following class:
public class MyCustomView extends RelativeLayout {
public MyCustomView(Context context) {
super(context);
init();
}
public MyCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_custom_view, this, true);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d("Widget", "Width spec: " + MeasureSpec.toString(widthMeasureSpec));
Log.d("Widget", "Height spec: " + MeasureSpec.toString(heightMeasureSpec));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int chosenWidth = chooseDimension(widthMode, widthSize);
int chosenHeight = chooseDimension(heightMode, heightSize);
int chosenDimension = Math.min(chosenWidth, chosenHeight);
setMeasuredDimension(chosenDimension, chosenDimension);
}
private int chooseDimension(int mode, int size) {
if (mode == MeasureSpec.AT_MOST || mode == MeasureSpec.EXACTLY) {
return size;
} else {
return getPreferredSize();
}
}
private int getPreferredSize() {
return 400;
}
}
As you can see I'm setting the root to MyCustomView instance and the attach flag to true.
What I want to achieve is that when I will add this custom view in another layout's xml, it will instantiate the MyCustomView class which will have the layout defined in the XML.
I already tries to use <merge> tag, but that way I lose the ability to arrange my child views in the XML as I want.
I also tried to inflate the XML and add it as a view to MyCustomView, but that way I get redundant RelativeLayout.
Last thing, I added the onMeasure() just for completeness.
the inflation occurs but the child view are not shown
The RelativeLayout does a bit more(a lot) than what you've done in the onMeasure layout(basically the children aren't measured at all with your code so they don't have something to show). If you extend a ViewGroup like RelativeLayout you need to let that class to do its callbacks(onMeasure, onLayout) or at least, very carefully replicate the methods and modify it like you want (if you want to see something).
So, remove the onMeasure method to see the children or explain better why did you override it.

Categories

Resources