mirror of
https://github.com/xoureldeen/Vectras-VM-Android.git
synced 2026-05-03 16:50:25 +00:00
385 lines
8.1 KiB
Java
385 lines
8.1 KiB
Java
package com.vectras.vm.adapter;
|
|
|
|
import androidx.lifecycle.Observer;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
import androidx.recyclerview.widget.RecyclerView.AdapterDataObserver;
|
|
import com.vectras.vm.logger.LogItem;
|
|
import java.util.Collections;
|
|
import android.widget.TextView;
|
|
import android.content.Context;
|
|
import android.view.ViewGroup;
|
|
import android.view.LayoutInflater;
|
|
import java.util.Vector;
|
|
import android.database.DataSetObserver;
|
|
import java.util.Date;
|
|
import android.text.format.DateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.Locale;
|
|
import android.os.Message;
|
|
import android.os.Bundle;
|
|
import android.os.Handler;
|
|
import android.view.View;
|
|
import com.vectras.vm.R;
|
|
import android.text.Html;
|
|
import android.view.MotionEvent;
|
|
import com.vectras.vm.logger.VectrasStatus;
|
|
|
|
public class LogsAdapter extends RecyclerView.Adapter<LogsAdapter.logViewHolder>
|
|
implements VectrasStatus.LogListener ,Handler.Callback,
|
|
View.OnTouchListener
|
|
{
|
|
private static final int MESSAGE_NEWLOG = 0;
|
|
|
|
private static final int MESSAGE_CLEARLOG = 1;
|
|
|
|
private static final int MESSAGE_NEWTS = 2;
|
|
private static final int MESSAGE_NEWLOGLEVEL = 3;
|
|
|
|
public static final int TIME_FORMAT_NONE = 0;
|
|
public static final int TIME_FORMAT_SHORT = 1;
|
|
public static final int TIME_FORMAT_ISO = 2;
|
|
private static final int MAX_STORED_LOG_ENTRIES = 1000;
|
|
|
|
private Vector<LogItem> allEntries = new Vector<>();
|
|
|
|
private Vector<LogItem> currentLevelEntries = new Vector<LogItem>();
|
|
|
|
private Handler mHandler;
|
|
private Context mContext;
|
|
private OnItemClickListener itemClickListener;
|
|
private LinearLayoutManager mLinearLayoutManager;
|
|
|
|
private Vector<AdapterDataObserver> observers = new Vector<>();
|
|
|
|
private int mTimeFormat = -100;
|
|
private int mLogLevel = 3;
|
|
private boolean mLockAutoScroll = false;
|
|
|
|
|
|
/**
|
|
* Interfaces
|
|
*/
|
|
|
|
public interface OnItemClickListener
|
|
{
|
|
void onItemClick(View view, int position, String logText);
|
|
void onItemLongClick(View view, int position, String logText);
|
|
}
|
|
|
|
public class logViewHolder extends RecyclerView.ViewHolder
|
|
{
|
|
TextView textLog;
|
|
|
|
logViewHolder(View itemView)
|
|
{
|
|
super(itemView);
|
|
|
|
this.textLog = itemView.findViewById(R.id.textLog);
|
|
}
|
|
}
|
|
|
|
|
|
public LogsAdapter(LinearLayoutManager layoutManager,
|
|
Context context)
|
|
{
|
|
this.mContext = context;
|
|
this.mLinearLayoutManager = layoutManager;
|
|
|
|
setLogLevel(VectrasStatus.LogLevel.DEBUG.getInt());
|
|
|
|
initLogBuffer();
|
|
if (mHandler == null)
|
|
{
|
|
mHandler = new Handler(this);
|
|
}
|
|
|
|
VectrasStatus.addLogListener(this);
|
|
}
|
|
|
|
public void setOnItemClickListener(OnItemClickListener listener) {
|
|
this.itemClickListener = listener;
|
|
}
|
|
|
|
private void initLogBuffer()
|
|
{
|
|
allEntries.clear();
|
|
Collections.addAll(allEntries, VectrasStatus.getlogbuffer());
|
|
initCurrentMessages();
|
|
}
|
|
|
|
private void initCurrentMessages()
|
|
{
|
|
currentLevelEntries.clear();
|
|
for (LogItem li : allEntries)
|
|
{
|
|
if (li.getLogLevel().getInt() <= mLogLevel)
|
|
currentLevelEntries.add(li);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public logViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
|
{
|
|
Context context = parent.getContext();
|
|
LayoutInflater inflater = LayoutInflater.from(context);
|
|
|
|
View logView = inflater.inflate(R.layout.list_item_log,
|
|
parent, false);
|
|
logView.setOnTouchListener(this);
|
|
|
|
return new logViewHolder(logView);
|
|
}
|
|
|
|
@Override
|
|
public void onBindViewHolder(final logViewHolder viewHolder,
|
|
final int position)
|
|
{
|
|
final String text;
|
|
|
|
try
|
|
{
|
|
LogItem logItem = currentLevelEntries.get(position);
|
|
String msg = logItem.getString(mContext);
|
|
String time = getTime(logItem, mTimeFormat);
|
|
text = (!time.isEmpty() ? String.format("[%s] ", time) : "") + msg;
|
|
viewHolder.textLog.setText(Html.fromHtml(text));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
VectrasStatus.logException(e);
|
|
return;
|
|
}
|
|
|
|
viewHolder.textLog.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v)
|
|
{
|
|
if (itemClickListener != null)
|
|
itemClickListener.onItemClick(v, position, text);
|
|
}
|
|
});
|
|
|
|
viewHolder.textLog.setOnLongClickListener(new View.OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View v)
|
|
{
|
|
if (itemClickListener != null)
|
|
itemClickListener.onItemLongClick(v, position, text);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer)
|
|
{
|
|
super.registerAdapterDataObserver(observer);
|
|
observers.add(observer);
|
|
}
|
|
|
|
@Override
|
|
public void unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver observer)
|
|
{
|
|
super.unregisterAdapterDataObserver(observer);
|
|
observers.remove(observer);
|
|
}
|
|
|
|
@Override
|
|
public int getItemCount()
|
|
{
|
|
return currentLevelEntries.size();
|
|
}
|
|
|
|
@Override
|
|
public long getItemId(int position)
|
|
{
|
|
return ((Object) currentLevelEntries.get(position)).hashCode();
|
|
}
|
|
|
|
public boolean isEmpty()
|
|
{
|
|
return currentLevelEntries.isEmpty();
|
|
}
|
|
|
|
@Override
|
|
public void onAttachedToRecyclerView(
|
|
RecyclerView recyclerView)
|
|
{
|
|
super.onAttachedToRecyclerView(recyclerView);
|
|
}
|
|
|
|
@Override
|
|
public boolean onTouch(View p1, MotionEvent event)
|
|
{
|
|
// aqui deveria pausar autoscroll
|
|
/*int action = event.getAction();
|
|
|
|
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_MOVE){
|
|
mLockAutoScroll = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
mLockAutoScroll = false;*/
|
|
|
|
return false;
|
|
}
|
|
|
|
private String getTime(LogItem le, int time)
|
|
{
|
|
if (time != TIME_FORMAT_NONE)
|
|
{
|
|
Date d = new Date(le.getLogtime());
|
|
java.text.DateFormat timeformat;
|
|
if (time == TIME_FORMAT_SHORT)
|
|
timeformat = new SimpleDateFormat("HH:mm a");
|
|
else
|
|
timeformat = DateFormat.getTimeFormat(mContext);
|
|
|
|
return timeformat.format(d);
|
|
|
|
}
|
|
else
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Handler implementação
|
|
*/
|
|
|
|
@Override
|
|
public boolean handleMessage(Message msg)
|
|
{
|
|
// We have been called
|
|
if (msg.what == MESSAGE_NEWLOG)
|
|
{
|
|
LogItem logMessage = msg.getData().getParcelable("logmessage");
|
|
if (addLogMessage(logMessage))
|
|
{
|
|
|
|
for (AdapterDataObserver observer : observers)
|
|
{
|
|
observer.onChanged();
|
|
}
|
|
|
|
if (!mLockAutoScroll)
|
|
scrollToLastPosition();
|
|
}
|
|
}
|
|
else if (msg.what == MESSAGE_CLEARLOG)
|
|
{
|
|
for (AdapterDataObserver observer : observers)
|
|
{
|
|
observer.onChanged();
|
|
}
|
|
initLogBuffer();
|
|
}
|
|
else if (msg.what == MESSAGE_NEWTS)
|
|
{
|
|
for (AdapterDataObserver observer : observers)
|
|
{
|
|
observer.onChanged();
|
|
}
|
|
}
|
|
else if (msg.what == MESSAGE_NEWLOGLEVEL)
|
|
{
|
|
initCurrentMessages();
|
|
|
|
for (AdapterDataObserver observer : observers)
|
|
{
|
|
observer.onChanged();
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param logmessage
|
|
* @return True if the current entries have changed
|
|
*/
|
|
private boolean addLogMessage(LogItem logmessage)
|
|
{
|
|
allEntries.add(logmessage);
|
|
|
|
if (allEntries.size() > MAX_STORED_LOG_ENTRIES)
|
|
{
|
|
Vector<LogItem> oldAllEntries = allEntries;
|
|
allEntries = new Vector<LogItem>(allEntries.size());
|
|
for (int i = 50; i < oldAllEntries.size(); i++)
|
|
{
|
|
allEntries.add(oldAllEntries.elementAt(i));
|
|
}
|
|
initCurrentMessages();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (logmessage.getLogLevel().getInt() <= mLogLevel)
|
|
{
|
|
currentLevelEntries.add(logmessage);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
public LogItem getItem(int position)
|
|
{
|
|
return currentLevelEntries.get(position);
|
|
}
|
|
|
|
public void clearLog()
|
|
{
|
|
// Actually is probably called from GUI Thread as result of the user
|
|
// pressing a button. But better safe than sorry
|
|
VectrasStatus.clearLog();
|
|
}
|
|
|
|
public void scrollToLastPosition()
|
|
{
|
|
// scroll para ultima mensagem
|
|
mLinearLayoutManager.scrollToPosition(
|
|
mLinearLayoutManager.getItemCount() - 1);
|
|
}
|
|
|
|
public void setLogLevel(int level) {
|
|
mLogLevel = level;
|
|
}
|
|
|
|
|
|
/**
|
|
* LogListener
|
|
*/
|
|
|
|
@Override
|
|
public void newLog(LogItem logMessage)
|
|
{
|
|
Message msg = Message.obtain();
|
|
|
|
assert (msg != null);
|
|
msg.what = MESSAGE_NEWLOG;
|
|
|
|
Bundle bundle = new Bundle();
|
|
bundle.putParcelable("logmessage", logMessage);
|
|
|
|
msg.setData(bundle);
|
|
mHandler.sendMessage(msg);
|
|
}
|
|
|
|
@Override
|
|
public void onClear()
|
|
{
|
|
mHandler.sendEmptyMessage(MESSAGE_CLEARLOG);
|
|
}
|
|
|
|
}
|