我的应用包含两个ExpandableHeightListViews和一个带共享垂直滚动的ExpandableHeightGridView。
从文件中读取视图的内容。这适用于小文件,数据显示正确并且活动加载。
然而,当选择大文件时,活动永远不会实际加载,当我调试它时,三个视图的适配器只是无休止地循环。我假设这是由于他们试图加载所有内容的观点的扩展性,但肯定可以避免这种情况吗?
这是代码......
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);
}
});
这三个适配器只是读取给定文件中的一些数据并相应地显示它。
有没有人知道如何修复此问题并使适配器视图仅加载必要的部分?
编辑:适配器代码......
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;
}
}