quinta-feira, 24 de abril de 2014

Delphi Android/iOS - Pull to Refresh


Esta vídeo aula tem como objetivo ensinar como criar um projeto FireMonkey Android/iOS conectado a um webservice datasnap para a conexão com o banco de dados, afim mostrar como fazer o refresh em um listview.


Também mostro como utilizar a função PacketRecord do ClientDataSet no listview, ensino como inserir os itens manualmente no listview, e dou uma dica especial para o Android. Espero que gostem, qualquer dúvida, sugestão ou comentário basta comentar aqui ou no meu blog. Abraços e bons estudos.

36 comentários:

  1. a função GetSelectedValue, funciona?

    ResponderExcluir
  2. como eu adiciono o ID no LookupData?

    ResponderExcluir
    Respostas
    1. Opa, então amigo, esse trem aí é só para o LiveBindings, manualmente não consegui fazer esse trem dar certo, porém, sempre tem uma segunda alternativa certo?! bom, faz umas alterações aí que vai dar certo:

      1º - Altere o código que carrega o listview e acrescenta uma linha, fica assim:
      ListItem.Data['IDEpisodio'] := ClientModule1.cdsSeries.FieldByName('id_episodio').AsInteger;

      2º - Altere a função GetSelectedValue para essa:
      function TForm2.GetSelectedValue(AObject: TObject): TValue;
      var
      Item: TListViewItem;
      begin
      if TListView(AObject).Selected <> nil then
      begin
      Item := TListView(AObject).Selected;
      Result := Item.Data['IDEpisodio'];
      end;
      end;

      Abraços e boa sorte

      Excluir
    2. Este comentário foi removido pelo autor.

      Excluir
    3. Nossa muito obrigado, cê é foda :)

      duvida: vou ter que fazer uma função pra cada listview? pra cada tabela?

      exemplo

      function GetSelectedValue(AObject: TObject): TValue;
      var
      Item: TListViewItem;
      begin
      if TListView(AObject).Selected <> nil then begin
      Item := TListView(AObject).Selected;
      Result := Item.Data['IDEpisodio];
      end;
      end;

      ai quero outra vou ter que criar tipo

      function GetSelectedValue(AObject: TObject): TValue;
      var
      Item: TListViewItem;
      begin
      if TListView(AObject).Selected <> nil then begin
      Item := TListView(AObject).Selected;
      Result := Item.Data['IDPessoa];
      end;
      end;

      ou posso fazer uma somente assim e usar em todos

      function GetSelectedValue(AObject: TObject): TValue;
      var
      Item: TListViewItem;
      begin
      if TListView(AObject).Selected <> nil then begin
      Item := TListView(AObject).Selected;
      Result := Item.Data['ID];
      end;
      end;


      Excluir
    4. agora quanto tempo usar o recno, do client data set tenho o seguinte erro: "At end of table"

      Excluir
  3. Deixa eu explicar melhor, tenho uma tabela Nomes, e outra Grupos ai Seleciono o Grupo , Escola em outra listview carrego os nomes da do grupo escola, mas quando eu seleciono um nome, tipo
    ID := GetSelectedValue(lstPessoas).ToString.ToInteger();
    CModulos.cdsPessoas.RecNo := ID;
    Nome := CModulos.cdsPessoas.FieldByName('P_NOME').AsString;

    ele não me retorna o nome correto selecionado, e da aquele erro a cima também, em alguns nomes u.u

    ResponderExcluir
    Respostas
    1. viajei, usei o Locate, e deu tudo certo, só resta a outra duvida mesmo, Desculpa haha :)

      Excluir
    2. Foram tantas perguntas que já nem sei qual é a outra dúvida kkkk

      Se for referente ao método, faz assim:
      function GetSelectedValue(AObject: TObject; AData: String): TValue;
      var
      Item: TListViewItem;
      begin
      if TListView(AObject).Selected <> nil then begin
      Item := TListView(AObject).Selected;
      Result := Item.Data[AData];
      end;
      end;

      Abraços

      Excluir
    3. Não posso usar em todos a mesma coisa? Result := Item.Data['ID'];

      Excluir
    4. Se vc quer um método genérico não, vc passar várias informações lá, por exemplo:

      lstItem.Data['item1'] := '';
      lstItem.Data['item2'] := ''; ...

      Mas pode fazer do jeito que achar melhor

      Excluir
  4. Olá Anderson, muito boa suas video aulas, tem me ajuda bastante. Parabéns! Precisava de umas dicas sua, estou fazendo um app android para consultar um servidor com firebird. Na rede interna ele funciona bem, na externa(3G) me tranquei, como devo fazer? Posso usar o no-ip para acessar o sevidor?

    ResponderExcluir
    Respostas
    1. Muito obrigado pelo comentário, é bom saber que continuo ajudando...

      Então, isso realmente é meio chato, na rede externa vc vai precisar saber configurar o roteador e tal, vc pode usar o no-ip para ajudar quanto ao ip mas mesmo assim vai precisar configurar o roteador/porta para direcionar para o ip (interno) correto, onde está o servidor de aplicação.

      Vai nesse caminho, configurar o roteador para fazer o redirecionamento correto a partir de uma determinada porta, quanto ao delphi não muda nada, só apontar para o ip ou dns correto.

      Abraços e boa sorte

      Excluir
    2. Obrigado pela resposta! Quanto a conexão externa ainda estou tentando resolver.Agora surgiu uma outra duvida, posso utilizar um listbox ao inves de listview? Qual a diferença entre os dois? obrigado pela atenção

      Excluir
    3. O listbox é para utilizar quando vc sabe a quantidade de itens, ou seja, vc vai adicionando manualmente para fazer uma lista pequena.

      O listview é para utilizar com o banco de dados, ou seja, quando vc não sabe a quantidade de itens, o que pode ser muitos ou não.

      Ou seja, listview é para usar com banco de dados, pois é mais rapido e listbox é para poucos registros.

      Se vc utilizar o listbox para banco de dados, vai demorar muito para montar os registros na tela.

      Excluir
    4. Este comentário foi removido pelo autor.

      Excluir
    5. Estava usando o listbox! hehe Qual a diferença entre o datasnap REST Application e o datasnap Server? Quando utilizar? Obrigado por compartilhar seu conhecimento...

      Excluir
    6. Bom, em resumo a diferença é simples.
      Basicamente é a mesma coisa, a grande diferença é que o REST usamos para quando não sabemos quem vai ser o cliente, ele é totalmente baseado em http, ou seja, o cliente pode ser java, c#, delphi...

      Agora no datasnap server é mais indicado para aplicações clientes feitos em delphi, sinceramente não sei se da para usar esse modo com outros clientes mas com o delphi fica perfeito.

      Tem mais coisas aí, o que falei foi o resumo da diferença, é bem mais complexo... Não exite em estudar um pouco sobre isso.

      Abraços

      Excluir
    7. Obrigado por estar sempre nos respondendo Anderson! Volto na pergunta que te fiz um tempo atrás, sobre utilizar o no-ip. Tu tinha dito sobre configurar roteador/porta, que porta seria essa? Liberei a porta que o datasnap utiliza a 211 esta correta? Nao teria mais nenhuma dica do que fazer??? Abraço

      Excluir
    8. Infelizmente não, sou péssimo em infra. Uma vez fiz e foi simples, liberei a porta no firewall, no caso foi a 211. Ajustei o roteador para quando receber uma requisição de uma porta qualquer, no meu teste era 7858 redirecionasse para o ip do servidor. Do mais não sei, detesto infra. kkk

      Excluir
    9. Olá Anderson, to aqui novamente enchendo o saco! hehe To tomando um laço pra fazer essa comunicação entre o servidor e o app android na rede externa. já liberei porta(211, 3050, 3055, 8888), já tentei conecta pelo endereço do no-ip, já fiz um monte de coisas e nada. Além do no-ip posso fazer esse tipo de comunicação de alguma outra maneira? Obrigado pela atenção!

      Excluir
  5. Olá Anderson,

    Estou com um problema no ListView, fiz um app de força de vendas que busca em um WebService os dados do sistema principal, mas quando vou listar o cadastro de pessoas ele não mostra todos, mostra uns 200 registros só, isso é uma limitação do ListView? O que tu me sugere fazer? Abraço e parabéns pelo blog.

    ResponderExcluir
    Respostas
    1. Muito obrigado Tarik... Então, não sei de limitação no ListView, inclusive já fiz testes com mais de 1000 registros e tudo ok, talvez tenha alguma coisa errado aí...

      Excluir
  6. Olá Anderson,

    você poderia fazer algum vídeo ou se tem alguma dica de como trabalhar com threads no mobile xe5 ou xe6? Tipo criando uma caixa de mensagem quando importamos registros, aquela velha mensagem "Aguarde..." "Carregando pedidos..." etc.

    ResponderExcluir
    Respostas
    1. Amigo, use esse componente http://delphiers.blogspot.com.br/2014/04/native-progress-dialogs-for-delphi-xe5.html e seja feliz.

      Abraços

      Excluir
    2. Anderson,

      eu já uso esse componente mas gostaria de saber se existe alguma forma de fazer isso em forma de código, sem precisar utilizar componentes de terceiros.

      Excluir
    3. Tem sim, eu já fiz mas esse é muito melhor...
      Para que re-inventar a roda??? kkk

      Excluir
    4. Tem razão kkk, mas a minha preocupação é com o suporte desse componente no futuro. Mas vc poderia me enviar o exemplo que você fez? Se pudesse eu agradeceria muito, desde já agradeço.

      Excluir
    5. kkkkkkkkkk não ficou bom e também quando descobri esse componente joguei meu código fora.

      Sem chance agora kkkk

      Excluir
    6. Blz, se algum dia descobrir algum outro método posta pra gente kkkk.

      Excluir
  7. Olá Anderson, Parabéns! Os vídeos são de grande ajuda para todos.

    Em minha instalação do XE6 eu não tenho os arquivos ".pas" apenas os ".dcu" é possível você me enviar o "FMX.Platform.Android.pas"? Estou fazendo o exemplo do "Pull to Refresh" mas está faltando a alteração no arquivo ".pas".
    Meu e-mail é o evandro_bonanca@yahoo.com.br

    Desde já agradeço!

    ResponderExcluir
  8. tarik, clica na ligacao q tem no bindsource com o listview, na propriedade AutoBufferCount e coloca ela como true, vai resolver, tenho uma tabela com 6000 registros mas so mostrava os 200, ai fiz isso e resolveu

    ResponderExcluir
  9. Olá Anderson, você teria algum exemplo sobre como fazer para o sistema executar uma determinada acão quando vc clica sobre um item no listview e mantém pressionado por algum tempo ??

    Desde já agradeço!!

    ResponderExcluir
  10. Parabéns pela video aula.
    Só gostaria de saber como eu faço para carregar dessa forma descrita na video aula as propriedades Detail1, Detail2, Detail3, pois só consigo acessar ListItem.Text e ListItem.Detail, e quando carrego o ListItem.Detail nada acontece.
    Gostaria de fazer o que o o livebings faz só que em run time.
    Você sabe como fazer?

    ResponderExcluir
  11. Olá Anderson, primeiramente quero de agradecer pela tua disposição em doar o teu tempo e conhecimento pra ajudar gente que você nem conhece.
    Aprendi muita coisa vendo os teus vídeos e tem me sido de grande ajuda mesmo.
    Estou desenvolvendo uma aplicação mobile usando DataSnap Rest. Uso os componentes do Firedac e venho trazendo sob demanda. No lado client vou colocando em memoria em um clientdataset. Como não estou usando o PacketRecords estou usando o Bind normalmente e esta funcionando muito bem.
    O problema e que como trago de 50 em 50 registros de cada vez o listview aponta sempre pro ultimo. Percebi no teu video que funciona assim também. Quer dizer, se eu estou vendo o registro 50 e atualizo ele, o listview vai mostrar o registro 100 e não o 51 em diante. Tem alguma ideia de como posso mudar isso?
    Um grande abraço.

    Robson Muniz

    ResponderExcluir
  12. ola é melhor usar o IBLite ou dbexpress?

    ResponderExcluir