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();
Related
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;
}
}
I have the following custom relative layout:
public class CircleView extends RelativeLayout implements OnDragListener {
private DropCallback onDrop = null;
private ImageButton imageButton = null;
private int radius = -1;
private double step = -1;
private double angle = -1;
private static final int CENTER_ID = 111;
public CircleView(Context context, DropCallback onDrop, int radius, List<View> views) {
super(context);
this.onDrop = onDrop;
this.radius = radius;
this.step = (2 * Math.PI) / views.size();
this.initView(context, views);
}
private void initView(Context context, List<View> views) {
RelativeLayout.LayoutParams layoutParamsView = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
this.setLayoutParams(layoutParamsView);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL);
this.imageButton = new ImageButton(context);
this.imageButton.setId(CENTER_ID);
this.imageButton.setLayoutParams(layoutParams);
this.imageButton.setImageResource(R.drawable.ic_power_on);
this.imageButton.getBackground().setAlpha(0);
this.imageButton.setOnDragListener(this);
this.addView(this.imageButton);
for(View view : views) {
this.addView(this.placeView(view));
}
}
private View placeView(View view) {
view.measure(0, 0);
this.imageButton.measure(0, 0);
int x = (int)((view.getMeasuredWidth() / 2) + this.radius * Math.cos(this.angle));
int y = (int)((view.getMeasuredHeight() / 2) + this.radius * Math.sin(this.angle));
this.angle += this.step;
int deltaX = view.getMeasuredWidth();
int deltaY = view.getMeasuredHeight();
int deltaImageX = this.imageButton.getMeasuredWidth() / 2;
int deltaImageY = this.imageButton.getMeasuredHeight() / 2;
int xToDraw = ((x - deltaX) - deltaImageX);
int yToDraw = ((y - deltaY) - deltaImageY);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.ABOVE, CENTER_ID);
layoutParams.addRule(RelativeLayout.RIGHT_OF, CENTER_ID);
layoutParams.setMargins(xToDraw, 0, 0, yToDraw);
view.setLayoutParams(layoutParams);
return view;
}
#Override
public boolean onDrag(View view, DragEvent event) {
return this.onDrop.onDrop(view, event);
}
}
I have no xml layout file for this and it worked until now.
Today i changed the activity using this custom layout to be a Fragment and i now need to set the layout. Unfortunately something like the following isnt possible:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
return inflater.inflate(new CircleView(this, this, 240, this.views), container, false);
}
So how can i inflate my custom relative layout?
Just create an instance of Circle view and add it to container :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
CircleView circleView = new CircleView(this, this, 240, this.views);
...
return circleView;
}
You should create you xml layout, for example circle_view.xml:
<your_package.CircleView android:id="#+id/gcircle_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
and then:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
return inflater.inflate(R.layout.circle_view, container, false);
}
btw, you should implement constructors:
public CircleView(Context context){
super(context);
}
public CircleView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public CircleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
You can create the inflator like this:
LayoutInflater inflater = LayoutInflater.from(context);
Then use the inflator to inflate the needed.
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()
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);
}
}
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